diff --git a/Assets/Scripts/Interaction/PingClickHandler.cs b/Assets/Scripts/Interaction/PingClickHandler.cs index 7c043df..b59b58e 100644 --- a/Assets/Scripts/Interaction/PingClickHandler.cs +++ b/Assets/Scripts/Interaction/PingClickHandler.cs @@ -8,6 +8,9 @@ public class PingClickHandler : MonoBehaviour private bool _modelShown; private bool _isBlinking; + // 静态变量,记录上一帧被点击的帧号,防止同一帧内多个 Ping 发生连锁反应 + private static int _lastClickedFrame = -1; + public bool CanBeClicked() { return _isBlinking; } void OnEnable() @@ -19,24 +22,25 @@ public class PingClickHandler : MonoBehaviour var colliders = GetComponents(); foreach (var c in colliders) { - if (c is SphereCollider || c is CapsuleCollider) + if (c is BoxCollider || c is CapsuleCollider) { Destroy(c); } } - var box = GetComponent(); - if (box == null) box = gameObject.AddComponent(); + var sphere = GetComponent(); + if (sphere == null) sphere = gameObject.AddComponent(); - Vector3 lossy = transform.lossyScale; - float sx = Mathf.Clamp(0.5f / Mathf.Max(Mathf.Abs(lossy.x), 0.001f), 0.001f, 100f); - float sy = Mathf.Clamp(0.5f / Mathf.Max(Mathf.Abs(lossy.y), 0.001f), 0.001f, 100f); - float sz = Mathf.Clamp(0.5f / Mathf.Max(Mathf.Abs(lossy.z), 0.001f), 0.001f, 100f); + // 核心修复:真实世界半径设定 + // 我们希望在 3D 世界里,这个点击热区的半径大约是 0.15 米(不大不小正好点击) + // 因为你的模型 lossyScale 达到了 100,所以局部 radius 必须除以 100 = 0.0015 + float maxScale = Mathf.Max(Mathf.Abs(transform.lossyScale.x), Mathf.Abs(transform.lossyScale.y), Mathf.Abs(transform.lossyScale.z)); + if (maxScale < 0.001f) maxScale = 1f; - box.size = new Vector3(sx, sy, sz); - box.center = Vector3.zero; - box.isTrigger = false; - box.enabled = true; + sphere.radius = 0.2f / maxScale; // 绝对保证世界半径是 0.2 米!不互相干涉 + sphere.center = Vector3.zero; + sphere.isTrigger = false; + sphere.enabled = true; CreateOutlineMesh(); _modelShown = false; @@ -72,34 +76,27 @@ public class PingClickHandler : MonoBehaviour while (true) { if (_outlineMesh != null) _outlineMesh.enabled = !_outlineMesh.enabled; yield return new WaitForSeconds(0.4f); } } - void OnMouseDown() - { - Debug.Log($"[PingClick] OnMouseDown 触发: {name}"); - PerformClick(); - } - void Update() { if (Input.GetMouseButtonDown(0)) { if (!_isBlinking) return; + // 解决 "一键点出多个" 的 BUG:同一帧内只能有一个物体被点中! + if (Time.frameCount == _lastClickedFrame) return; + foreach (var c in Camera.allCameras) { if (!c.enabled) continue; Ray ray = c.ScreenPointToRay(Input.mousePosition); - // 使用超长射线,无视距离 - RaycastHit[] hits = Physics.RaycastAll(ray, 10000f); + RaycastHit[] hits = Physics.RaycastAll(ray, 1000f); foreach (var hit in hits) { if (hit.collider != null && hit.collider.gameObject == gameObject) { Debug.Log($"[PingClick] Update手动射线贯穿点中 (使用相机: {c.name}): {name}"); - - // FIX BUG: Prevent multiple clicks in the same frame - _isBlinking = false; - + _lastClickedFrame = Time.frameCount; // 锁定这一帧,别的 ping 不准再触发 PerformClick(); return; }