diff --git a/Assets/Scripts/Interaction/PingClickHandler.cs b/Assets/Scripts/Interaction/PingClickHandler.cs
index a06159d..22e8c02 100644
--- a/Assets/Scripts/Interaction/PingClickHandler.cs
+++ b/Assets/Scripts/Interaction/PingClickHandler.cs
@@ -50,32 +50,13 @@ public class PingClickHandler : MonoBehaviour
while (true) { if (_outlineMesh != null) _outlineMesh.enabled = !_outlineMesh.enabled; yield return new WaitForSeconds(0.4f); }
}
- ///
- /// 全新的点击检测方式:由一个静态方法统一管理,不再依赖碰撞体。
- /// 在 Update 里,遍历所有活跃的 PingClickHandler,找到离鼠标最近的那个,只触发它。
- ///
void Update()
{
- // 只让 pingIndex 最小的那个实例来做全局检测,避免多个实例重复执行
+ // 只有正在闪烁的 ping 才参与检测
if (!_isBlinking) return;
-
- // 只有一个实例负责全局判断
- var allHandlers = FindObjectsOfType();
- bool iAmFirst = true;
- foreach (var h in allHandlers)
- {
- if (!h._isBlinking) continue;
- if (h.GetInstanceID() < this.GetInstanceID())
- {
- iAmFirst = false;
- break;
- }
- }
- if (!iAmFirst) return;
-
if (!Input.GetMouseButtonDown(0)) return;
- // 不在 UI 上才检测
+ // 如果点在 UI 上,不处理
if (UnityEngine.EventSystems.EventSystem.current != null &&
UnityEngine.EventSystems.EventSystem.current.IsPointerOverGameObject())
return;
@@ -91,36 +72,34 @@ public class PingClickHandler : MonoBehaviour
}
if (activeCamera == null) return;
- // 遍历所有正在闪烁的 ping,找到距离鼠标最近的那个
- float bestDist = float.MaxValue;
- PingClickHandler bestPing = null;
+ // 计算自己到鼠标的屏幕距离
+ Vector3 screenPos = activeCamera.WorldToScreenPoint(transform.position);
+ if (screenPos.z < 0) return; // 在相机背后
Vector2 mousePos = Input.mousePosition;
+ float myDist = Vector2.Distance(mousePos, new Vector2(screenPos.x, screenPos.y));
+ // 检查是否有其他正在闪烁的 ping 比我更近
+ var allHandlers = FindObjectsOfType();
foreach (var h in allHandlers)
{
+ if (h == this) continue;
if (!h._isBlinking) continue;
if (!h.gameObject.activeInHierarchy) continue;
- Vector3 screenPos = activeCamera.WorldToScreenPoint(h.transform.position);
+ Vector3 otherScreen = activeCamera.WorldToScreenPoint(h.transform.position);
+ if (otherScreen.z < 0) continue;
- // 如果在相机背后,跳过
- if (screenPos.z < 0) continue;
-
- float dist = Vector2.Distance(mousePos, new Vector2(screenPos.x, screenPos.y));
- if (dist < bestDist)
- {
- bestDist = dist;
- bestPing = h;
- }
+ float otherDist = Vector2.Distance(mousePos, new Vector2(otherScreen.x, otherScreen.y));
+ if (otherDist < myDist) return; // 别人比我更近,让别人处理
}
- // 点击半径阈值:80像素以内算点中(可以根据需要调整)
- if (bestPing != null && bestDist < 80f)
+ // 我是离鼠标最近的闪烁中的 ping!
+ if (myDist < 80f)
{
- Debug.Log($"[PingClick] 屏幕坐标命中: {bestPing.name} (距离={bestDist:F1}px)");
- bestPing._isBlinking = false;
- bestPing.PerformClick();
+ Debug.Log($"[PingClick] 屏幕坐标命中: {name} (距离={myDist:F1}px)");
+ _isBlinking = false;
+ PerformClick();
}
}
@@ -166,38 +145,15 @@ public class PingClickHandler : MonoBehaviour
var sm = FindObjectOfType();
if (sm != null) sm.RecordPingStep(pingIndex, true);
- var remainingPings = Object.FindObjectsOfType();
- int activePingCount = 0;
- foreach (var p in remainingPings)
- {
- if (p._isBlinking || p._modelShown) activePingCount++;
- }
-
- // 自己刚刚隐藏了,所以要减 1 看看还剩几个
- // 其实更准确的是检查 collider enabled,但现在我们不用 collider 了
- // 直接看有没有剩余的活跃 ping
- bool allDone = true;
- foreach (var p in Object.FindObjectsOfType())
- {
- var c = p.GetComponent();
- // 如果还有没被隐藏的 ping(依然可见),就说明没完
- if (p.gameObject.activeInHierarchy && p._modelShown && !p._isBlinking)
- {
- // 这个 ping 已经完成了第一阶段但还没进入第二阶段
- // 不算完成
- }
- }
-
- // 简单判定:遍历所有的 ping,看看是否还有 collider enabled 的
var pings = Object.FindObjectsOfType();
int remaining = 0;
foreach (var p in pings)
{
- var col = p.GetComponent();
- if (col != null && col.enabled) remaining++;
+ if (p.gameObject.activeInHierarchy && (p._isBlinking || p._modelShown))
+ remaining++;
}
-
- if (remaining == 0)
+ // 自己刚刚 HideSelf 了,如果没有其他活跃的 ping 了
+ if (remaining <= 1)
{
Debug.Log("[PingClick] 所有的 ping 都已经绑成 chanrao 了!播放完成语音。");
var am = FindObjectOfType();
@@ -281,7 +237,6 @@ public class PingClickHandler : MonoBehaviour
public void ResetState()
{
_modelShown = false;
-
_isBlinking = true;
if (_modelRenderer != null) _modelRenderer.enabled = false;
foreach (var r in GetComponentsInChildren(true)) { if (_outlineMesh != null && r == _outlineMesh) continue; r.enabled = false; }