diff --git a/Assets/Scripts/Interaction/PingClickHandler.cs b/Assets/Scripts/Interaction/PingClickHandler.cs index 22e8c02..9b774a3 100644 --- a/Assets/Scripts/Interaction/PingClickHandler.cs +++ b/Assets/Scripts/Interaction/PingClickHandler.cs @@ -8,10 +8,17 @@ public class PingClickHandler : MonoBehaviour private bool _modelShown; private bool _isBlinking; + // 全局静态变量,防止同一帧内有多个 PingClickHandler 被同时触发 + private static int _lastClickedFrame = -1; + // 实例变量,记录自己被启用(或重新闪烁)的那一帧 + private int _enableFrame = -1; + public bool CanBeClicked() { return _isBlinking; } void OnEnable() { + _enableFrame = Time.frameCount; + _modelRenderer = GetComponent(); if (_modelRenderer == null) _modelRenderer = GetComponentInChildren(); foreach (var r in GetComponentsInChildren(true)) r.enabled = false; @@ -52,10 +59,16 @@ public class PingClickHandler : MonoBehaviour void Update() { - // 只有正在闪烁的 ping 才参与检测 + // 只检测正在闪烁的 ping if (!_isBlinking) return; if (!Input.GetMouseButtonDown(0)) return; + // 防御 1:防止刚被激活的同一帧内立刻触发(比如点击鞋子的一瞬间 ping.004 被激活,此时鼠标左键按下状态依然为 true) + if (Time.frameCount == _enableFrame) return; + + // 防御 2:防止同一帧内有多个 ping 同时触发(执行顺序导致的状态延迟问题) + if (Time.frameCount == _lastClickedFrame) return; + // 如果点在 UI 上,不处理 if (UnityEngine.EventSystems.EventSystem.current != null && UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject()) @@ -95,9 +108,10 @@ public class PingClickHandler : MonoBehaviour } // 我是离鼠标最近的闪烁中的 ping! - if (myDist < 80f) + if (myDist < 120f) // 稍微放宽一点阈值,120像素内都算点中 { Debug.Log($"[PingClick] 屏幕坐标命中: {name} (距离={myDist:F1}px)"); + _lastClickedFrame = Time.frameCount; // 锁定当前帧,其他 ping 不准再触发 _isBlinking = false; PerformClick(); } @@ -184,6 +198,7 @@ public class PingClickHandler : MonoBehaviour } _isBlinking = true; + _enableFrame = Time.frameCount; // 防止重置瞬间被点中 if (_outlineMesh != null) { @@ -206,6 +221,7 @@ public class PingClickHandler : MonoBehaviour ShowSelf(); _modelShown = true; _isBlinking = true; + _enableFrame = Time.frameCount; // 防止重置瞬间被点中 if (_outlineMesh != null) _outlineMesh.enabled = true; StopAllCoroutines(); StartCoroutine(BlinkOutline()); @@ -238,6 +254,7 @@ public class PingClickHandler : MonoBehaviour { _modelShown = false; _isBlinking = true; + _enableFrame = Time.frameCount; // 防止重置瞬间被点中 if (_modelRenderer != null) _modelRenderer.enabled = false; foreach (var r in GetComponentsInChildren(true)) { if (_outlineMesh != null && r == _outlineMesh) continue; r.enabled = false; } if (_outlineMesh != null) _outlineMesh.enabled = true;