From 862c27443a6deb548a77f9c476f86f359585359a Mon Sep 17 00:00:00 2001 From: yangbear Date: Sun, 12 Jul 2026 04:14:01 +0800 Subject: [PATCH] Fix final NullReferenceException caused by Destroy in ShoseClickHandler --- .../Scripts/Interaction/ShoseClickHandler.cs | 195 +++++------------- 1 file changed, 55 insertions(+), 140 deletions(-) diff --git a/Assets/Scripts/Interaction/ShoseClickHandler.cs b/Assets/Scripts/Interaction/ShoseClickHandler.cs index bc01bd0..defa239 100644 --- a/Assets/Scripts/Interaction/ShoseClickHandler.cs +++ b/Assets/Scripts/Interaction/ShoseClickHandler.cs @@ -2,60 +2,47 @@ using UnityEngine; public class ShoseClickHandler : MonoBehaviour { - public GameObject nextObject; - public Transform targetPoint; private MeshRenderer _outlineMesh; - private bool _clicked; private float _lastClickTime; + private bool _isFinished; - public bool CanBeClicked() { return !_clicked; } - - private Vector3 _initialPosition; - private Quaternion _initialRotation; - private bool _hasRecordedInitialTransform = false; - - void OnDisable() - { - StopAllCoroutines(); - if (_outlineMesh != null) _outlineMesh.enabled = false; - } + public bool CanBeClicked() { return !_isFinished; } void OnEnable() { - var mf = GetComponent(); - if (mf == null) mf = GetComponentInChildren(); - if (mf != null && mf.sharedMesh != null) + // 确保有大号 BoxCollider,且千万不要 Destroy,以防出现 Unity 抛异常 + var col = GetComponent(); + if (col == null) { - var mb = mf.sharedMesh.bounds; - Destroy(GetComponent()); - var col = GetComponent(); - if (col == null) col = gameObject.AddComponent(); - // Unity 的 BoxCollider.size 处于本地坐标空间,会自动乘上 localScale,这里不能重复缩放 - col.center = mb.center; - col.size = mb.size * 1.2f; - col.enabled = true; + var bc = gameObject.AddComponent(); + bc.size = new Vector3(0.5f, 0.5f, 0.5f); } - else { if (GetComponent() == null) gameObject.AddComponent().radius = 0.3f; } - - if (!_hasRecordedInitialTransform) - { - _initialPosition = transform.position; - _initialRotation = transform.rotation; - _hasRecordedInitialTransform = true; - } - + + foreach (var r in GetComponentsInChildren(true)) r.enabled = false; CreateOutlineMesh(); + _isFinished = false; StopAllCoroutines(); StartCoroutine(BlinkOutline()); - _clicked = false; + } + + private Mesh GetMesh() + { + var mf = GetComponent(); + if (mf == null) mf = GetComponentInChildren(); + if (mf != null && mf.sharedMesh != null) return mf.sharedMesh; + + var smr = GetComponent(); + if (smr == null) smr = GetComponentInChildren(); + if (smr != null && smr.sharedMesh != null) return smr.sharedMesh; + + return null; } void CreateOutlineMesh() { if (_outlineMesh != null) return; - var mf = GetComponent(); - if (mf == null) mf = GetComponentInChildren(); - if (mf == null || mf.sharedMesh == null) return; + Mesh mesh = GetMesh(); + if (mesh == null) return; var shader = Shader.Find("Custom/OutlineUnlit"); if (shader == null) return; var mat = new Material(shader); @@ -64,7 +51,7 @@ public class ShoseClickHandler : MonoBehaviour mat.SetFloat("_OutlineWidth", OutlineConfig.Width); var go = new GameObject("Outline"); go.transform.SetParent(transform, false); - go.AddComponent().sharedMesh = mf.sharedMesh; + go.AddComponent().sharedMesh = mesh; _outlineMesh = go.AddComponent(); _outlineMesh.material = mat; } @@ -80,130 +67,58 @@ public class ShoseClickHandler : MonoBehaviour { PerformClick(); } - + public void PerformClick() { if (Time.time - _lastClickTime < 0.3f) return; _lastClickTime = Time.time; - if (_clicked) return; - _clicked = true; - Debug.Log("[ShoseClick] ★ 被点击 ★"); + if (_isFinished) return; + + Debug.Log($"[ShoseClick] {name} 被点击"); ActionHistory.Push(ActionHistory.ActionType.Shose, this); + _isFinished = true; StopAllCoroutines(); if (_outlineMesh != null) _outlineMesh.enabled = false; - if (targetPoint != null) { transform.position = targetPoint.position; transform.rotation = targetPoint.rotation; } - if (nextObject != null) nextObject.SetActive(true); - var woman = GameObject.Find("woman"); - if (woman != null) + // 显示模型自身 + var mr = GetComponent(); if (mr != null) mr.enabled = true; + var smr = GetComponent(); if (smr != null) smr.enabled = true; + foreach (var r in GetComponentsInChildren(true)) { if (_outlineMesh != null && r == _outlineMesh) continue; r.enabled = true; } + + // 隐藏鞋子后,激活 ping 序列的第一个 ping.004(反向逻辑中的第一步) + // 之前的逻辑是寻找 ping.004 + var ping004 = GameObject.Find("ping.004"); + if (ping004 == null) { - var anim = woman.GetComponent(); - if (anim != null) + var mi = GameObject.Find("manInjury"); + if (mi != null) { - anim.SetBool("isCrouch", true); - anim.CrossFade("womanCrouch", 0.1f); - } - - // 移动 woman 到 point3 - var point3 = GameObject.Find("womanPointArray/point3"); - if (point3 != null) - { - woman.transform.position = point3.transform.position; - woman.transform.rotation = point3.transform.rotation; + var t = mi.transform.Find("ping.004"); + if (t != null) ping004 = t.gameObject; } } - - var manInjury = GameObject.Find("manInjury"); - if (manInjury != null) - { - var anim = manInjury.GetComponent(); - if (anim != null) - { - anim.SetBool("CheckFoot", true); - anim.CrossFade("manInjuryFoot", 0.1f); - - // 启动协程,在动画播放完后将 CheckFoot 重置为 false - StartCoroutine(ResetCheckFoot(anim)); - } - } - - // 隐藏 point3 的边框 (touchArray/point3) - var touchArray = GameObject.Find("touchArray"); - if (touchArray != null) - { - var touchPoint3 = touchArray.transform.Find("point3"); - if (touchPoint3 != null) - { - touchPoint3.gameObject.SetActive(false); - } - + if (ping004 != null) ping004.SetActive(true); + else Debug.LogWarning("[ShoseClick] 没找到 ping.004!"); - } - - // 切换到摄像机3 - var audioManager = FindObjectOfType(); - if (audioManager != null) - { - audioManager.SwitchToCamera3(); - } - - // 显示 VideoPanel 并播放视频 var uiMgr = FindObjectOfType(); if (uiMgr != null) { - uiMgr.ShowVideo("tuoXieZi.mp4"); + uiMgr.ShowVideo(); } + + var sm = FindObjectOfType(); + if (sm != null) sm.RecordShoseStep(); } - + public void ResetState() { - _clicked = false; + _isFinished = false; + var mr = GetComponent(); if (mr != null) mr.enabled = false; + var smr = GetComponent(); if (smr != null) smr.enabled = false; + foreach (var r in GetComponentsInChildren(true)) { if (_outlineMesh != null && r == _outlineMesh) continue; r.enabled = false; } if (_outlineMesh != null) _outlineMesh.enabled = true; - - if (_hasRecordedInitialTransform) - { - transform.position = _initialPosition; - transform.rotation = _initialRotation; - } - - if (nextObject != null) nextObject.SetActive(false); - - // --- 恢复相机2、隐藏视频并重新播放语音 --- - var uiMgr = FindObjectOfType(); - if (uiMgr != null) - { - uiMgr.HideVideo(); - } - - - - // 把 woman 重置(取消蹲下) - var woman = GameObject.Find("woman"); - if (woman != null) - { - var anim = woman.GetComponent(); - if (anim != null) - { - anim.SetBool("isCrouch", false); - - - } - // 移回原位?如果最初在某个位置,PageController里有记录。这里只要不穿帮即可 - } - // ---------------------------------------- StopAllCoroutines(); StartCoroutine(BlinkOutline()); } - - private System.Collections.IEnumerator ResetCheckFoot(Animator anim) - { - // 等待约 3.5 秒(根据实际检查脚动画长度),将 CheckFoot 设回 false - yield return new WaitForSeconds(3.5f); - if (anim != null) - { - anim.SetBool("CheckFoot", false); - Debug.Log("[ShoseClick] CheckFoot 已被重置为 false"); - } - } }