From 5d669b442932451235bcfa64cdaac5731a641c83 Mon Sep 17 00:00:00 2001 From: yangbear Date: Sun, 12 Jul 2026 05:52:29 +0800 Subject: [PATCH] Fix: disable camera switch on Shose click + prevent ping double-trigger with 2-frame cooldown --- .../Scripts/Interaction/PingClickHandler.cs | 19 +++++++++++++------ .../Scripts/Interaction/ShoseClickHandler.cs | 4 ++-- 2 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Assets/Scripts/Interaction/PingClickHandler.cs b/Assets/Scripts/Interaction/PingClickHandler.cs index b59b58e..bf3c1ad 100644 --- a/Assets/Scripts/Interaction/PingClickHandler.cs +++ b/Assets/Scripts/Interaction/PingClickHandler.cs @@ -11,10 +11,15 @@ public class PingClickHandler : MonoBehaviour // 静态变量,记录上一帧被点击的帧号,防止同一帧内多个 Ping 发生连锁反应 private static int _lastClickedFrame = -1; + // 新生成的 ping 在激活后的前2帧不允许被点击,防止被射线立刻打中 + private int _enabledFrame = -1; + public bool CanBeClicked() { return _isBlinking; } void OnEnable() { + _enabledFrame = Time.frameCount; // 记录被激活的帧号 + _modelRenderer = GetComponent(); if (_modelRenderer == null) _modelRenderer = GetComponentInChildren(); foreach (var r in GetComponentsInChildren(true)) r.enabled = false; @@ -31,13 +36,10 @@ public class PingClickHandler : MonoBehaviour var sphere = GetComponent(); if (sphere == null) sphere = gameObject.AddComponent(); - // 核心修复:真实世界半径设定 - // 我们希望在 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; - sphere.radius = 0.2f / maxScale; // 绝对保证世界半径是 0.2 米!不互相干涉 + sphere.radius = 0.15f / maxScale; // 缩小到 0.15 米,防止多个 ping 碰撞体重叠 sphere.center = Vector3.zero; sphere.isTrigger = false; sphere.enabled = true; @@ -82,8 +84,11 @@ public class PingClickHandler : MonoBehaviour { if (!_isBlinking) return; - // 解决 "一键点出多个" 的 BUG:同一帧内只能有一个物体被点中! + // 同一帧只能有一个 ping 被触发 if (Time.frameCount == _lastClickedFrame) return; + + // 刚被激活的前2帧不允许被点击(防止 nextPing 被立即触发) + if (Time.frameCount - _enabledFrame < 2) return; foreach (var c in Camera.allCameras) { @@ -96,7 +101,8 @@ public class PingClickHandler : MonoBehaviour if (hit.collider != null && hit.collider.gameObject == gameObject) { Debug.Log($"[PingClick] Update手动射线贯穿点中 (使用相机: {c.name}): {name}"); - _lastClickedFrame = Time.frameCount; // 锁定这一帧,别的 ping 不准再触发 + _lastClickedFrame = Time.frameCount; + _isBlinking = false; PerformClick(); return; } @@ -188,6 +194,7 @@ public class PingClickHandler : MonoBehaviour } _isBlinking = true; + _enabledFrame = Time.frameCount; // 重新激活时也要保护2帧 if (col != null) col.enabled = true; if (_outlineMesh != null) diff --git a/Assets/Scripts/Interaction/ShoseClickHandler.cs b/Assets/Scripts/Interaction/ShoseClickHandler.cs index 13ac182..8ca12b1 100644 --- a/Assets/Scripts/Interaction/ShoseClickHandler.cs +++ b/Assets/Scripts/Interaction/ShoseClickHandler.cs @@ -140,11 +140,11 @@ public class ShoseClickHandler : MonoBehaviour } - // 切换到摄像机3 + // 切换到摄像机3(已由 PageController 开场动画结束时完成,此处不再重复触发) var audioManager = FindObjectOfType(); if (audioManager != null) { - audioManager.SwitchToCamera3(); + // audioManager.SwitchToCamera3(); // 已由开场流程切换,不重复 } // 显示 VideoPanel 并播放视频