using System.Linq; using Core; using UnityEngine; using Script.Gameplay.Connect; using Script.Gameplay.Interface; using Script.Gameplay.Input; using System; using UnityEngine.InputSystem; namespace Script.Gameplay.Player { public class PlayerConnectController : MonoBehaviour { private bool _isEnablePlayerConnecting = false; public bool IsEnablePlayerConnecting { get => _isEnablePlayerConnecting; set { _isEnablePlayerConnecting = value; if (_isEnablePlayerConnecting == false) { // 重置当前目标 CurrentTarget = null; previousGazedTarget = null; outTarget = null; inputTarget = null; } } } // 是否启用连接功能 [SerializeField] private FirstPersonRaycaster raycaster; // 第一人称射线检测器 [SerializeField] private float maxConnectDistance = 10f; // 最大连接距离 private IConnectable previousTarget; private IConnectable currentTarget; public IConnectable CurrentTarget { get => currentTarget; set { previousTarget = currentTarget; currentTarget = value; if (previousTarget != currentTarget) { if (currentTarget != null) { OnGazeEnterConnectable?.Invoke((currentTarget as MonoBehaviour)?.gameObject); } if (previousTarget != null) { OnGazeExitConnectable?.Invoke((previousTarget as MonoBehaviour)?.gameObject); } } } } // 当前注视的可连接对象 private IConnectable previousGazedTarget; // 上一次注视的 IConnectable(用于触发进入/离开) private InputManager inputManager; private IConnectable outTarget; private IConnectable inputTarget; public event Action OnSetPointA; public event Action OnSetPointB; public event Action OnGazeEnterConnectable; public event Action OnGazeExitConnectable; void Start() { inputManager = InputManager.Instance; inputManager.Input.Player.SetOutput.performed += OnSetOutputOnperformed; inputManager.Input.Player.SetInput.performed += OnSetInputOnperformed; inputManager.Input.Player.Connect.performed += OnConnectOnperformed; inputManager.Input.Player.CutLine.performed += OnCutLineOnperformed; 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); } private void OnCutLineOnperformed(InputAction.CallbackContext ctx) { CutConnectLine(CurrentTarget); } private void OnConnectOnperformed(InputAction.CallbackContext ctx) { CreateConnection(); } private void OnSetInputOnperformed(InputAction.CallbackContext ctx) { SetPointB(CurrentTarget); } private void OnSetOutputOnperformed(InputAction.CallbackContext ctx) { SetPointA(CurrentTarget); } void Update() { DetectConnectable(); } void DetectConnectable() { if (raycaster == null) return; if(!IsEnablePlayerConnecting) return; GameObject lookAtObj = raycaster.CurrentLookAtObject; IConnectable hitConnectable = lookAtObj != null ? lookAtObj.GetComponent() : null; CurrentTarget = hitConnectable; } public void SetPointA(IConnectable target) { if (target == null) return; if (!IsEnablePlayerConnecting) return; if (!target.IsEnableConnect) return; outTarget = target; OnSetPointA?.Invoke(outTarget); } public void SetPointB(IConnectable target) { if (target == null) return; if (!IsEnablePlayerConnecting) return; if (!target.IsEnableConnect) return; inputTarget = target; OnSetPointB?.Invoke(inputTarget); } public void CutConnectLine(IConnectable target) { if (target == null) return; if(!IsEnablePlayerConnecting) return; ConnectionLineManager.Instance.CutTargetConnectionLines(target); } private void CreateConnection() { if(!IsEnablePlayerConnecting) return; if (outTarget != null && inputTarget != null && outTarget != inputTarget) { //计算距离 float distance = Vector3.Distance(outTarget.GetPosition(), inputTarget.GetPosition()); if (distance > maxConnectDistance) { Debug.Log("Cannot create connection: targets are too far apart."); return; } // 创建连接线 ConnectionLine connectionLine = ConnectionLineManager.Instance.GenerateConnectionLine(outTarget, inputTarget); // 重置信号目标 outTarget = null; inputTarget = null; } else { Debug.Log("Cannot create connection: invalid targets."); } } private void OnDestroy() { ControllerLocator.Instance.Unregister(this); inputManager.Input.Player.SetOutput.performed -= OnSetOutputOnperformed; inputManager.Input.Player.SetInput.performed -= OnSetInputOnperformed; inputManager.Input.Player.Connect.performed -= OnConnectOnperformed; inputManager.Input.Player.CutLine.performed -= OnCutLineOnperformed; } void OnDrawGizmos() { // 射线可视化交由 FirstPersonRaycaster 处理 } } }