Unity中替换Debug.Log为SetActive后C#代码失效,求故障原因
问题分析与修复方案
你的代码核心问题出在逻辑判断错误和变量未重置上,导致替换成canvas.SetActive后逻辑失效,具体问题和修复如下:
核心问题
count变量未重置:每次调用IsInRange()时,count不会被重置为0,会持续累加数值,后续的count != hitColliders.Length判断完全失效,逻辑彻底混乱。- 冗余且错误的判断逻辑:遍历碰撞体时,找到玩家后未终止循环,还在处理其他碰撞体;用
count来间接判断玩家是否存在的方式完全没必要,还容易出错。 - Canvas禁用后的检测原点失效:当
canvas.SetActive(false)后,其transform.position可能无法正确更新,导致OverlapSphere的检测原点错误,后续无法正确识别玩家范围。
修复后的代码
// 建议提前在Inspector中赋值一个专门的检测点(始终激活的空物体) public Transform detectionPoint; private void Update() { bool playerIsInRange = IsInRange(); canvas.SetActive(playerIsInRange); } private bool IsInRange() { // 使用独立检测点的位置,避免Canvas禁用后原点失效 Vector3 origin = detectionPoint != null ? detectionPoint.position : canvas.transform.position; Collider[] hitColliders = Physics.OverlapSphere(origin, range, playerLayer); foreach (var hitCollider in hitColliders) { // 用对象引用对比代替名字判断,更可靠(避免重名问题) if (hitCollider.gameObject == player) { playerInRange = true; playerInRangeF1 = true; return true; // 找到玩家直接返回,无需继续遍历 } } // 未找到玩家时重置状态 playerInRange = false; playerInRangeF1 = false; return false; }
修复说明
- 移除了冗余的
count变量,直接在遍历中检测玩家,找到后立即返回true,逻辑更清晰高效。 - 新增独立检测点:用一个始终激活的空物体作为范围检测的原点,彻底避免Canvas禁用后检测位置失效的问题。
- 替换名字对比为对象引用对比:避免因重名导致的误判,逻辑更稳定。
- 统一在未找到玩家时重置状态变量,确保状态同步。
内容的提问来源于stack exchange,提问作者JoshMann15
相关产品推荐
相关产品推荐

