Fix ping.001 first phase collider issue and clear old colliders safely

This commit is contained in:
yangbear
2026-07-12 03:47:42 +08:00
parent 76a6691ffc
commit 26063858a3
+26 -27
View File
@@ -16,25 +16,29 @@ public class PingClickHandler : MonoBehaviour
if (_modelRenderer == null) _modelRenderer = GetComponentInChildren<MeshRenderer>();
foreach (var r in GetComponentsInChildren<Renderer>(true)) r.enabled = false;
// 确保碰撞体是打开的
var col = GetComponent<Collider>();
if (col == null)
// 彻底清掉旧的 Collider,重新添加一个绝对靠谱的 SphereCollider
var colliders = GetComponents<Collider>();
foreach(var c in colliders)
{
var sphere = gameObject.AddComponent<SphereCollider>();
sphere.radius = 0.5f; // 可以适当增加,保证能点到
col = sphere;
Destroy(c);
}
else if (col is BoxCollider bc)
// 重新添加足够大、形状简单的球形碰撞器
var sphere = gameObject.AddComponent<SphereCollider>();
// 获取物体本身的渲染边界,如果没有则使用固定值
if (_modelRenderer != null)
{
// 如果是之前的 BoxCollider,把它改大一点,确保能点到
bc.size = new Vector3(Mathf.Max(bc.size.x, 0.8f), Mathf.Max(bc.size.y, 0.8f), Mathf.Max(bc.size.z, 0.8f));
// 通过 bounds 的大小来估算一个适合的半径
float maxDim = Mathf.Max(_modelRenderer.bounds.size.x, Mathf.Max(_modelRenderer.bounds.size.y, _modelRenderer.bounds.size.z));
sphere.radius = Mathf.Max(maxDim * 0.6f, 0.5f);
}
else if (col is SphereCollider sc)
else
{
sc.radius = Mathf.Max(sc.radius, 0.5f);
sphere.radius = 0.5f;
}
col.enabled = true;
// 强制碰撞体处于启用状态
sphere.enabled = true;
CreateOutlineMesh();
_modelShown = false;
@@ -57,7 +61,6 @@ public class PingClickHandler : MonoBehaviour
mat.SetFloat("_OutlineWidth", OutlineConfig.Width);
var go = new GameObject("Outline");
go.transform.SetParent(transform, false);
// 稍微往上偏移一点点,防止边框插进地里
go.transform.position += Vector3.up * 0.05f;
go.AddComponent<MeshFilter>().sharedMesh = mf.sharedMesh;
_outlineMesh = go.AddComponent<MeshRenderer>();
@@ -99,8 +102,6 @@ public class PingClickHandler : MonoBehaviour
if (nextPing != null) nextPing.SetActive(true);
else
{
// 如果 nextPing 是 null,说明我是最后一个 ping(也就是 ping.001
// 此时第一阶段结束,激活 chanraotuibu
var chanraotuibu = GameObject.Find("chanraotuibu");
if (chanraotuibu == null)
{
@@ -129,13 +130,10 @@ public class PingClickHandler : MonoBehaviour
var sm = FindObjectOfType<StepManager>();
if (sm != null) sm.RecordPingStep(pingIndex, true);
// 判断是否是真正的最后一步:检查所有的 PingClickHandler,看是否还有 activeInHierarchy 的。
// 注意当前 gameObject 刚刚被 SetActive(false),所以 FindObjectsOfType 获取不到当前的对象了。
var remainingPings = Object.FindObjectsOfType<PingClickHandler>();
int activePingCount = 0;
foreach (var p in remainingPings)
{
// In phase 2, finished pings have their collider disabled and _isBlinking set to false.
var col = p.GetComponent<Collider>();
if (col != null && col.enabled) activePingCount++;
}
@@ -152,7 +150,6 @@ public class PingClickHandler : MonoBehaviour
#endif
}
// 隐藏视频面板
var uiMgr = FindObjectOfType<UIManager>();
if (uiMgr != null)
{
@@ -164,11 +161,8 @@ public class PingClickHandler : MonoBehaviour
public void ReEnableBorder()
{
// 关键:在第二阶段被激活时,先检查我们是否已经被完成了
// 只有 _modelShown 为 true,并且没有被最终隐藏时,才能被激活
if (!_modelShown) return;
// 如果模型已经被替换成 chanrao 并且隐藏了自己,就不应该再被激活
var col = GetComponent<Collider>();
if (chanraoObject != null && chanraoObject.activeSelf)
{
@@ -177,8 +171,6 @@ public class PingClickHandler : MonoBehaviour
}
_isBlinking = true;
// 【关键修复点】:确保即使在第二次激活时,碰撞体也被打开,且如果有的话,保证能被点到。
if (col != null) col.enabled = true;
if (_outlineMesh != null)
@@ -235,11 +227,18 @@ public class PingClickHandler : MonoBehaviour
public void ResetState()
{
_modelShown = false;
// 【关键修复点:重置状态时确保重新添加或修复 Collider】
var col = GetComponent<Collider>();
if (col != null) col.enabled = true;
if (col == null)
{
col = gameObject.AddComponent<SphereCollider>();
((SphereCollider)col).radius = 0.5f;
}
col.enabled = true;
_isBlinking = true;
if (_modelRenderer != null) _modelRenderer.enabled = false;
// 隐藏自身模型
foreach (var r in GetComponentsInChildren<Renderer>(true)) { if (_outlineMesh != null && r == _outlineMesh) continue; r.enabled = false; }
if (_outlineMesh != null) _outlineMesh.enabled = true;
StopAllCoroutines();