using System.Linq; using Core; using UnityEngine; using Script.Gameplay.Connect; using Script.Gameplay.Input; using System; namespace Script.Gameplay.Player { public class PlayerConnectController : MonoBehaviour { public bool IsEnableConnecting = true; // 是否启用连接功能 [SerializeField] private FirstPersonRaycaster raycaster; // 第一人称射线检测器 private IConnectable currentTarget; // 当前注视的可连接对象 private IConnectable previousGazedTarget; // 上一次注视的 IConnectable(用于触发进入/离开) private InputManager inputManager; private IConnectable outTarget; private IConnectable inputTarget; public event Action OnSetOutputTarget; public event Action OnSetInputTarget; void Start() { inputManager = InputManager.Instance; inputManager.Input.Player.SetOutput.performed += ctx => SetOutTarget(currentTarget); inputManager.Input.Player.SetInput.performed += ctx => SetInputTarget(currentTarget); inputManager.Input.Player.Connect.performed += ctx => CreateConnection(); inputManager.Input.Player.CutLine.performed += ctx => CutConnectLine(currentTarget); 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."); ControllerLocator.Instance.Register(this); } void Update() { DetectConnectable(); } void DetectConnectable() { if (raycaster == null) return; GameObject lookAtObj = raycaster.CurrentLookAtObject; IConnectable hitConnectable = lookAtObj != null ? lookAtObj.GetComponent() : null; // 注视对象变化时触发进入/离开(使用接口方法) if (hitConnectable != previousGazedTarget) { if (previousGazedTarget != null) { previousGazedTarget.OnGazeExit(); } if (hitConnectable != null) { hitConnectable.OnGazeEnter(); } previousGazedTarget = hitConnectable; } currentTarget = hitConnectable; } public IConnectable GetCurrentTarget() { return currentTarget; } public void SetOutTarget(IConnectable target) { if (target == null) return; if(!IsEnableConnecting) return; if (!target.IsConnectedOutput) { outTarget = target; OnSetOutputTarget?.Invoke(outTarget); } } public void SetInputTarget(IConnectable target) { if (target == null) return; if(!IsEnableConnecting) return; if (!target.IsConnectedInput) { inputTarget = currentTarget; OnSetInputTarget?.Invoke(inputTarget); } } public void CutConnectLine(IConnectable target) { if (target == null) return; if(target.OutputConnectionLine != null && target.InputConnectionLine != null) return; target.OutputConnectionLine?.DeleteConnection(); target.InputConnectionLine?.DeleteConnection(); } private void CreateConnection() { if(!IsEnableConnecting) return; if (outTarget != null && inputTarget != null && outTarget != inputTarget) { ConnectionLine connectionLine = ConnectionLineManager.Instance.GenerateConnectionLine(outTarget, inputTarget); outTarget.OutputConnectionLine = connectionLine; inputTarget.InputConnectionLine = connectionLine; // 重置信号目标 outTarget = null; inputTarget = null; } else { Debug.Log("Cannot create connection: invalid targets."); } } void OnDrawGizmos() { // 射线可视化交由 FirstPersonRaycaster 处理 } } }