using UnityEngine; using Interface; using System; using Script.Gameplay.Input; namespace Gameplay.Player { public class PlayerInteractorController : MonoBehaviour { [SerializeField] private float interactRange = 15f; [SerializeField] private LayerMask interactableLayer; [SerializeField] private Camera playerCamera; [SerializeField] private bool isDrawGizmos; private IInteractable currentTarget; // 被射线命中的当前可交互对象(用于按键交互) private IInteractable previousGazedTarget; // 上一次注视的对象(用于注视进入/离开事件) void Start() { if (playerCamera == null) playerCamera = GameObject.FindWithTag("MainCamera").GetComponent(); var input = InputManager.Instance.Input; input.Player.SwitchWatchMode.performed += ctx => currentTarget.Interact(this.gameObject);; } void Update() { DetectInteractable(); } void DetectInteractable() { if (playerCamera == null) return; Ray ray = new Ray(playerCamera.transform.position, playerCamera.transform.forward); if (Physics.Raycast(ray, out RaycastHit hit, interactRange, interactableLayer)) { IInteractable hitInteractable = hit.collider.GetComponent(); // 如果命中对象与之前注视的不一样,触发进入/离开事件 if (hitInteractable != previousGazedTarget) { if (previousGazedTarget != null) { previousGazedTarget.OnGazeExit(this.gameObject); } if (hitInteractable != null) { hitInteractable.OnGazeEnter(this.gameObject); // 这里可以显示交互提示UI,例如 “E - 开门” Debug.Log(hitInteractable.GetInteractPrompt()); } previousGazedTarget = hitInteractable; } currentTarget = hitInteractable; } else { // 没有命中时,如果之前有注视对象,触发离开 if (previousGazedTarget != null) { previousGazedTarget.OnGazeExit(this.gameObject); previousGazedTarget = null; } currentTarget = null; } } void OnDrawGizmos() { if (isDrawGizmos) return; if (playerCamera == null) return; Gizmos.color = Color.green; Vector3 origin = playerCamera.transform.position; Vector3 direction = playerCamera.transform.forward * interactRange; Gizmos.DrawLine(origin, origin + direction); } } }