using UnityEngine; using Script.Gameplay.Interface; using System; using Core; using Script.Gameplay.Input; using UnityEngine.InputSystem; namespace Script.Gameplay.Player { public class PlayerInteractorController : MonoBehaviour { [SerializeField] private FirstPersonRaycaster raycaster; // 新增:第一人称射线检测器 [SerializeField] private bool isEnablePlayerInteraction = true; // 是否启用玩家交互功能 private IInteractable previousTarget; private IInteractable currentTarget; private IInteractable CurrentTarget { get => currentTarget; set { previousTarget = currentTarget; currentTarget = value; if (previousTarget != currentTarget) { if (currentTarget != null) { OnGazeEnter?.Invoke((currentTarget as MonoBehaviour)?.gameObject); } if (previousTarget != null) { OnGazeExit?.Invoke((previousTarget as MonoBehaviour)?.gameObject); } } } } // 被射线命中的当前可交互对象(用于按键交互) public event Action OnGazeEnter; public event Action OnGazeExit; void Start() { if (raycaster == null) raycaster = GetComponent() ?? GetComponentInChildren(); if (raycaster == null) raycaster = FindObjectOfType(); if (raycaster == null) Debug.LogWarning("FirstPersonRaycaster not found! Please assign or add it to the player."); var input = InputManager.Instance.Input; input.Player.Interact.performed += OnInteractOnperformed; ControllerLocator.Instance.Register(this); } private void OnInteractOnperformed(InputAction.CallbackContext ctx) { if (CurrentTarget == null) return; if (!CurrentTarget.IsEnableInteract) return; CurrentTarget.Interact(this.gameObject); } void Update() { DetectInteractable(); } void DetectInteractable() { if (raycaster == null) return; if (!isEnablePlayerInteraction) return; GameObject lookAtObj = raycaster.CurrentLookAtObject; IInteractable hitInteractable = lookAtObj != null ? lookAtObj.GetComponent() : null; CurrentTarget = hitInteractable; } public void SetPlayerInteractionEnabled(bool isEnabled) { isEnablePlayerInteraction = isEnabled; if (!isEnabled) { CurrentTarget = null; } } private void OnDestroy() { ControllerLocator.Instance.Unregister(this); var input = InputManager.Instance.Input; input.Player.Interact.performed -= OnInteractOnperformed; } void OnDrawGizmos() { // 交由 FirstPersonRaycaster 绘制射线 } } }