From 0a1aa83425d68b87a349ab82dddccff507f5e1d8 Mon Sep 17 00:00:00 2001 From: GanX <2423855310@qq.com> Date: Mon, 20 Oct 2025 19:40:55 +0800 Subject: [PATCH] =?UTF-8?q?refactor(Connect):=20=E9=87=8D=E6=9E=84?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E4=BD=93=E7=B3=BB=EF=BC=8C=E5=AE=9E=E7=8E=B0?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E7=89=A9=E4=BD=93=E6=8B=A5=E6=9C=89=E5=A4=9A?= =?UTF-8?q?=E4=B8=AA=E8=BF=9E=E6=8E=A5=E7=BA=BF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Script/Gameplay/Connect/ConnectionLine.cs | 91 ++++++++++--------- .../Gameplay/Connect/ConnectionLineManager.cs | 23 ++++- .../Script/Gameplay/Connect/IConnectable.cs | 9 +- .../Script/Gameplay/Connect/ISignalSender.cs | 8 ++ .../Gameplay/Connect/ISignalSender.cs.meta | 3 + .../Facility/ButtonInteractController.cs | 41 +++++---- .../Facility/DoorInteractController.cs | 19 ++-- .../Facility/LeverInteractController.cs | 47 ++++++---- .../Facility/PressurePlateController.cs | 51 +++++++---- .../Player/PlayerConnectController.cs | 31 +++---- .../Script/Gameplay/UI/PlayerConnectViewer.cs | 4 +- 11 files changed, 187 insertions(+), 140 deletions(-) create mode 100644 Assets/Script/Gameplay/Connect/ISignalSender.cs create mode 100644 Assets/Script/Gameplay/Connect/ISignalSender.cs.meta diff --git a/Assets/Script/Gameplay/Connect/ConnectionLine.cs b/Assets/Script/Gameplay/Connect/ConnectionLine.cs index 1b1531b..4659769 100644 --- a/Assets/Script/Gameplay/Connect/ConnectionLine.cs +++ b/Assets/Script/Gameplay/Connect/ConnectionLine.cs @@ -6,66 +6,73 @@ namespace Script.Gameplay.Connect // 只负责在场景中绘制连接线,并处理信号传递 public class ConnectionLine : MonoBehaviour { - [SerializeField] private MonoBehaviour monoSource; - [SerializeField] private MonoBehaviour monoTarget; - private IConnectable _output; - private IConnectable _input; + [SerializeField] private MonoBehaviour monoPointA; + [SerializeField] private MonoBehaviour monoPointB; + private IConnectable _pointA; + private IConnectable _pointB; private LineRenderer line; private void Awake() { - _output = monoSource as IConnectable; - _input = monoTarget as IConnectable; + _pointA = monoPointA as IConnectable; + _pointB = monoPointB as IConnectable; line = GetComponent(); - if (_output != null && _input != null) + SetLineRendererPositions(); + } + + public void SetConnectable(IConnectable pointA, IConnectable pointB) + { + if(pointA == null || pointB == null) { - SetConnectable(_output, _input); + Debug.Log("ConnectionLine requires two valid IConnectable points."); + return; } - } - - public void SetConnectable(IConnectable output, IConnectable input) - { - _output = output; - _input = input; - _output.IsConnectedOutput = true; - _input.IsConnectedInput = true; - - line.SetPositions(new Vector3[] + if (pointA == pointB) { - _output.GetPosition(), - _input.GetPosition() - }); - } - - public void ReceiveSignal(bool active) - { - SendSignal(active); - } - - private void SendSignal(bool active) - { - _input.ReceiveSignal(active,this.gameObject); + Debug.Log("ConnectionLine cannot connect the same point."); + return; + } + _pointA = pointA; + _pointB = pointB; + pointA.ConnectionLines.Add(this); + pointB.ConnectionLines.Add(this); + SetLineRendererPositions(); } - public void DeleteConnection() + private void SetLineRendererPositions() { - Destroy(this.gameObject); + if (_pointA != null && _pointB != null) + { + line.SetPositions(new Vector3[] + { + _pointA.GetPosition(), + _pointB.GetPosition() + }); + } + } + + public void SignalActive(bool active, GameObject sender) + { + if (_pointA != null && _pointB != null) + { + if (sender == _pointA.GetGameObject()) + { + _pointB.SignalActive(active, sender); + } + else if (sender == _pointB.GetGameObject()) + { + _pointA.SignalActive(active, sender); + } + } } private void OnDestroy() { - if (_output != null) - { - _output.IsConnectedOutput = false; - } - - if (_input != null) - { - _input.IsConnectedInput = false; - } + _pointA.ConnectionLines.Remove(this); + _pointB.ConnectionLines.Remove(this); } } } \ No newline at end of file diff --git a/Assets/Script/Gameplay/Connect/ConnectionLineManager.cs b/Assets/Script/Gameplay/Connect/ConnectionLineManager.cs index e322ff8..a56bc8c 100644 --- a/Assets/Script/Gameplay/Connect/ConnectionLineManager.cs +++ b/Assets/Script/Gameplay/Connect/ConnectionLineManager.cs @@ -23,20 +23,35 @@ namespace Script.Gameplay.Connect GeneratePreviousConnectionLines(preConnectionLines); } - public ConnectionLine GenerateConnectionLine(IConnectable source, IConnectable target) + public ConnectionLine GenerateConnectionLine(IConnectable a, IConnectable b) { GameObject lineObject = Instantiate(linePrefab, this.transform); ConnectionLine connectionLine = lineObject.GetComponent(); if (connectionLine != null) { - source.OutputConnectionLine = connectionLine; - target.InputConnectionLine = connectionLine; - connectionLine.SetConnectable(source, target); + connectionLine.SetConnectable(a, b); connectionLines.Add(connectionLine); return connectionLine; } return null; } + + public void CutTargetConnectionLines(IConnectable target) + { + List linesToRemove = new List(); + foreach (var line in connectionLines) + { + if (line != null && (line.Equals(target))) + { + linesToRemove.Add(line); + } + } + foreach (var line in linesToRemove) + { + connectionLines.Remove(line); + Destroy(line.gameObject); + } + } public void GeneratePreviousConnectionLines(List previousConnections) { diff --git a/Assets/Script/Gameplay/Connect/IConnectable.cs b/Assets/Script/Gameplay/Connect/IConnectable.cs index c1e57b3..5cfab6e 100644 --- a/Assets/Script/Gameplay/Connect/IConnectable.cs +++ b/Assets/Script/Gameplay/Connect/IConnectable.cs @@ -8,12 +8,9 @@ namespace Script.Gameplay.Connect void OnGazeEnter(); // 玩家开始注视时触发 void OnGazeExit(); // 玩家停止注视时触发 Vector3 GetPosition(); // 获取连接点位置 + GameObject GetGameObject(); // 获取连接点物体 string GetConnectableName(); // 获取连接点名称 - public ConnectionLine OutputConnectionLine { get; set; } - public ConnectionLine InputConnectionLine { get; set; } - bool IsConnectedOutput { get; set; } // 是否作为输出端连接 - bool IsConnectedInput { get; set; } // 是否作为输入端连接 - void ReceiveSignal(bool active, GameObject sender); // 接收信号 - void SendSignal(bool active, GameObject sender); // 发出信号 + public List ConnectionLines { get; set; } + void SignalActive(bool active, GameObject sender); // 被激活 } } \ No newline at end of file diff --git a/Assets/Script/Gameplay/Connect/ISignalSender.cs b/Assets/Script/Gameplay/Connect/ISignalSender.cs new file mode 100644 index 0000000..3b18cba --- /dev/null +++ b/Assets/Script/Gameplay/Connect/ISignalSender.cs @@ -0,0 +1,8 @@ +using UnityEngine; +namespace Script.Gameplay.Connect +{ + public interface ISignalSender + { + public void SendSignal(bool active); + } +} \ No newline at end of file diff --git a/Assets/Script/Gameplay/Connect/ISignalSender.cs.meta b/Assets/Script/Gameplay/Connect/ISignalSender.cs.meta new file mode 100644 index 0000000..97a6c00 --- /dev/null +++ b/Assets/Script/Gameplay/Connect/ISignalSender.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: dc3af72006f342c3b8b7526a5b09e6ee +timeCreated: 1760958923 \ No newline at end of file diff --git a/Assets/Script/Gameplay/Facility/ButtonInteractController.cs b/Assets/Script/Gameplay/Facility/ButtonInteractController.cs index 9dfab46..8a166cb 100644 --- a/Assets/Script/Gameplay/Facility/ButtonInteractController.cs +++ b/Assets/Script/Gameplay/Facility/ButtonInteractController.cs @@ -1,11 +1,12 @@ using System.Collections; +using System.Collections.Generic; using UnityEngine; using Script.Gameplay.Interface; using Script.Gameplay.Connect; namespace Script.Gameplay.Facility { - public class ButtonInteractController : MonoBehaviour, IInteractable, IEditableComponent, IConnectable + public class ButtonInteractController : MonoBehaviour, IInteractable, IEditableComponent, IConnectable, ISignalSender { #region Interactable @@ -20,7 +21,7 @@ namespace Script.Gameplay.Facility public void Interact(GameObject interactor) { if (!Interactable) return; - StartCoroutine(SendSignalCoroutine(interactor)); + StartCoroutine(SendSignalCoroutine()); Debug.Log("Button pressed"); } @@ -34,14 +35,15 @@ namespace Script.Gameplay.Facility // 可选:取消高亮 } - private IEnumerator SendSignalCoroutine(GameObject sender) + private IEnumerator SendSignalCoroutine() { - SendSignal(true, sender); + SendSignal(true); + Interactable = false; // 按钮压下的动画或效果可以在这里添加 yield return new WaitForSeconds(signalDuration); - - SendSignal(false, sender); + SendSignal(false); + Interactable = true; // 按钮弹起的动画或效果可以在这里添加 } @@ -81,27 +83,30 @@ namespace Script.Gameplay.Facility return transform.position; } + public GameObject GetGameObject() + { + return gameObject; + } + public string GetConnectableName() { return gameObject.name; } - public ConnectionLine OutputConnectionLine { get; set; } - public ConnectionLine InputConnectionLine { get; set; } - - public bool IsConnectedOutput { get; set; } - public bool IsConnectedInput { get; set; } - - public void ReceiveSignal(bool active, GameObject sender) + public List ConnectionLines { get; set; } = new List(); + public void SignalActive(bool active, GameObject sender) { - // 按钮通常不响应输入信号,可留空或自定义逻辑 + // 按钮通常不接收信号,因此这里可以留空 } - - public void SendSignal(bool active, GameObject sender) + + public void SendSignal(bool active) { - if (OutputConnectionLine != null) + if (ConnectionLines != null) { - OutputConnectionLine.ReceiveSignal(active); + foreach (var line in ConnectionLines) + { + line.SignalActive(active, this.gameObject); + } } } diff --git a/Assets/Script/Gameplay/Facility/DoorInteractController.cs b/Assets/Script/Gameplay/Facility/DoorInteractController.cs index c1339b1..6691c33 100644 --- a/Assets/Script/Gameplay/Facility/DoorInteractController.cs +++ b/Assets/Script/Gameplay/Facility/DoorInteractController.cs @@ -95,27 +95,22 @@ namespace Script.Gameplay.Facility return transform.position; } + public GameObject GetGameObject() + { + return gameObject; + } + public string GetConnectableName() { return gameObject.name; } - public ConnectionLine OutputConnectionLine { get; set; } - public ConnectionLine InputConnectionLine { get; set; } - - public bool IsConnectedOutput { get; set; } - public bool IsConnectedInput { get; set; } - - public void ReceiveSignal(bool active, GameObject sender) + public List ConnectionLines { get; set; } = new List(); + public void SignalActive(bool active, GameObject sender) { Interact(sender); } - public void SendSignal(bool active, GameObject sender) - { - OutputConnectionLine.ReceiveSignal(active); - } - #endregion } } \ No newline at end of file diff --git a/Assets/Script/Gameplay/Facility/LeverInteractController.cs b/Assets/Script/Gameplay/Facility/LeverInteractController.cs index e3ef810..3ff43e6 100644 --- a/Assets/Script/Gameplay/Facility/LeverInteractController.cs +++ b/Assets/Script/Gameplay/Facility/LeverInteractController.cs @@ -1,10 +1,11 @@ +using System.Collections.Generic; using UnityEngine; using Script.Gameplay.Interface; using Script.Gameplay.Connect; namespace Script.Gameplay.Facility { - public class LeverInteractController : MonoBehaviour, IInteractable, IEditableComponent, IConnectable + public class LeverInteractController : MonoBehaviour, IInteractable, IEditableComponent, IConnectable, ISignalSender { #region Interactable @@ -20,7 +21,7 @@ namespace Script.Gameplay.Facility { if (!Interactable) return; isPulled = !isPulled; - SendSignal(isPulled, interactor); + SendSignal(isPulled); // 可选:拉杆动画 Debug.Log(isPulled ? "Lever pulled down" : "Lever reset"); } @@ -58,29 +59,39 @@ namespace Script.Gameplay.Facility #region Connectable - public void OnGazeEnter() { } - public void OnGazeExit() { } - public Vector3 GetPosition() => transform.position; - public string GetConnectableName() => gameObject.name; - public ConnectionLine OutputConnectionLine { get; set; } - public ConnectionLine InputConnectionLine { get; set; } - public bool IsConnectedOutput { get; set; } - public bool IsConnectedInput { get; set; } - - public void ReceiveSignal(bool active, GameObject sender) + public void OnGazeEnter() { - // 拉杆通常不响应输入信号 } - public void SendSignal(bool active, GameObject sender) + public void OnGazeExit() { - if (OutputConnectionLine != null) + } + + public Vector3 GetPosition() => transform.position; + public GameObject GetGameObject() + { + return gameObject; + } + + public string GetConnectableName() => gameObject.name; + public List ConnectionLines { get; set; }= new List(); + + public void SignalActive(bool active, GameObject sender) + { + // + } + + public void SendSignal(bool active) + { + if (ConnectionLines != null) { - OutputConnectionLine.ReceiveSignal(active); + foreach (var line in ConnectionLines) + { + line.SignalActive(active, this.gameObject); + } } } #endregion } -} - +} \ No newline at end of file diff --git a/Assets/Script/Gameplay/Facility/PressurePlateController.cs b/Assets/Script/Gameplay/Facility/PressurePlateController.cs index 8df9181..657c25d 100644 --- a/Assets/Script/Gameplay/Facility/PressurePlateController.cs +++ b/Assets/Script/Gameplay/Facility/PressurePlateController.cs @@ -1,10 +1,11 @@ +using System.Collections.Generic; using UnityEngine; using Script.Gameplay.Interface; using Script.Gameplay.Connect; namespace Script.Gameplay.Facility { - public class PressurePlateController : MonoBehaviour, IEditableComponent, IConnectable + public class PressurePlateController : MonoBehaviour, IEditableComponent, IConnectable, ISignalSender { [SerializeField] private bool isActive = true; [SerializeField] private LayerMask detectLayer = ~0; // 检测所有层,可在Inspector中指定 @@ -16,10 +17,11 @@ namespace Script.Gameplay.Facility private void FixedUpdate() { if (!isActive) return; - bool hasObject = Physics.CheckBox(transform.position + plateOffset, plateSize * 0.5f, Quaternion.identity, detectLayer); + bool hasObject = Physics.CheckBox(transform.position + plateOffset, plateSize * 0.5f, Quaternion.identity, + detectLayer); if (hasObject != lastState) { - SendSignal(hasObject, gameObject); + SendSignal(hasObject); lastState = hasObject; } } @@ -39,25 +41,37 @@ namespace Script.Gameplay.Facility #region Connectable - public void OnGazeEnter() { } - public void OnGazeExit() { } - public Vector3 GetPosition() => transform.position; - public string GetConnectableName() => gameObject.name; - public ConnectionLine OutputConnectionLine { get; set; } - public ConnectionLine InputConnectionLine { get; set; } - public bool IsConnectedOutput { get; set; } - public bool IsConnectedInput { get; set; } - - public void ReceiveSignal(bool active, GameObject sender) + public void OnGazeEnter() { - // 压力板不响应输入信号 } - public void SendSignal(bool active, GameObject sender) + public void OnGazeExit() { - if (OutputConnectionLine != null) + } + + public Vector3 GetPosition() => transform.position; + + public GameObject GetGameObject() + { + return gameObject; + } + + public string GetConnectableName() => gameObject.name; + public List ConnectionLines { get; set; } = new List(); + + public void SignalActive(bool active, GameObject sender) + { + // + } + + public void SendSignal(bool active) + { + if (ConnectionLines != null) { - OutputConnectionLine.ReceiveSignal(active); + foreach (var line in ConnectionLines) + { + line.SignalActive(active, this.gameObject); + } } } @@ -71,5 +85,4 @@ namespace Script.Gameplay.Facility } #endif } -} - +} \ No newline at end of file diff --git a/Assets/Script/Gameplay/Player/PlayerConnectController.cs b/Assets/Script/Gameplay/Player/PlayerConnectController.cs index f804bdb..e6e5cd9 100644 --- a/Assets/Script/Gameplay/Player/PlayerConnectController.cs +++ b/Assets/Script/Gameplay/Player/PlayerConnectController.cs @@ -19,14 +19,14 @@ namespace Script.Gameplay.Player private IConnectable outTarget; private IConnectable inputTarget; - public event Action OnSetOutputTarget; - public event Action OnSetInputTarget; + public event Action OnSetPointA; + public event Action OnSetPointB; void Start() { inputManager = InputManager.Instance; - inputManager.Input.Player.SetOutput.performed += ctx => SetOutTarget(currentTarget); - inputManager.Input.Player.SetInput.performed += ctx => SetInputTarget(currentTarget); + inputManager.Input.Player.SetOutput.performed += ctx => SetPointA(currentTarget); + inputManager.Input.Player.SetInput.performed += ctx => SetPointB(currentTarget); inputManager.Input.Player.Connect.performed += ctx => CreateConnection(); inputManager.Input.Player.CutLine.performed += ctx => CutConnectLine(currentTarget); @@ -77,34 +77,27 @@ namespace Script.Gameplay.Player return currentTarget; } - public void SetOutTarget(IConnectable target) + public void SetPointA(IConnectable target) { if (target == null) return; if(!IsEnableConnecting) return; - if (!target.IsConnectedOutput) - { - outTarget = target; - OnSetOutputTarget?.Invoke(outTarget); - } + outTarget = target; + OnSetPointA?.Invoke(outTarget); } - public void SetInputTarget(IConnectable target) + public void SetPointB(IConnectable target) { if (target == null) return; if(!IsEnableConnecting) return; - if (!target.IsConnectedInput) - { - inputTarget = currentTarget; - OnSetInputTarget?.Invoke(inputTarget); - } + inputTarget = target; + OnSetPointB?.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(); + if(!IsEnableConnecting) return; + ConnectionLineManager.Instance.CutTargetConnectionLines(target); } private void CreateConnection() diff --git a/Assets/Script/Gameplay/UI/PlayerConnectViewer.cs b/Assets/Script/Gameplay/UI/PlayerConnectViewer.cs index 8961a1b..85c453f 100644 --- a/Assets/Script/Gameplay/UI/PlayerConnectViewer.cs +++ b/Assets/Script/Gameplay/UI/PlayerConnectViewer.cs @@ -23,8 +23,8 @@ namespace UI private void OnGetConnectController(PlayerConnectController controller) { _playerConnectController = controller; - _playerConnectController.OnSetInputTarget += UpdateInputText; - _playerConnectController.OnSetOutputTarget += UpdateOutputText; + _playerConnectController.OnSetPointB += UpdateInputText; + _playerConnectController.OnSetPointA += UpdateOutputText; UpdateInputText(null); UpdateOutputText(null); }