Unity追逐游戏逻辑异常:触发碰撞后玩家仍2秒死亡问题
问题分析与修复方案
你的代码存在三个核心问题,导致逻辑异常:
- 未处理碰撞离开事件:只有
OnTriggerStay2D将touching设为true,但没有OnTriggerExit2D在离开碰撞范围时把touching改为false,这会导致touching状态无法正确更新。 - 每帧重复启动协程:
Update每帧都调用AddScore,意味着每帧都会启动新的协程——即使touching为true,也会每秒生成一堆空协程;如果touching为false,会同时启动大量死亡倒计时协程,即便后续回到碰撞范围,之前的协程仍会执行销毁操作。 - 得分逻辑无控制:当前每帧都执行
score++,配合1秒协程根本无法实现“每秒加1分”的效果,得分会疯狂增长。
修复后的完整代码
using System.Collections; using System.Collections.Generic; using UnityEngine; public class Trigger : MonoBehaviour { public GameObject player; // 重命名为player,语义更清晰 bool isTouching; // 采用驼峰命名,符合C#规范 int score = 0; Coroutine deathCoroutine; // 保存死亡协程实例,方便中途停止 private void Update() { // 无需每帧调用得分逻辑,得分逻辑放在协程中控制 } private void OnTriggerEnter2D(Collider2D other) { isTouching = true; // 进入碰撞时,停止正在运行的死亡协程 if (deathCoroutine != null) { StopCoroutine(deathCoroutine); deathCoroutine = null; } // 仅启动一次得分协程 StartCoroutine(ScorePerSecond()); } private void OnTriggerStay2D(Collider2D other) { isTouching = true; // 持续刷新状态,避免意外状态错误 } private void OnTriggerExit2D(Collider2D other) { isTouching = false; // 离开时仅启动一次死亡倒计时协程 if (deathCoroutine == null) { deathCoroutine = StartCoroutine(DeathCountdown()); } } IEnumerator ScorePerSecond() { // 处于碰撞范围内时,每秒加1分 while (isTouching) { score++; Debug.Log($"当前得分:{score}"); yield return new WaitForSeconds(1f); } } IEnumerator DeathCountdown() { yield return new WaitForSeconds(2f); // 确认不在碰撞范围再销毁 if (!isTouching) { Destroy(player); } } }
关键修复点说明
- 添加
OnTriggerExit2D:处理离开碰撞的逻辑,更新isTouching状态并启动死亡倒计时。 - 协程实例管理:用
deathCoroutine跟踪死亡协程,进入碰撞时立即停止倒计时,避免误销毁。 - 得分逻辑重构:将得分逻辑放在循环协程中,仅在碰撞范围内每秒加1分,避免每帧重复操作。
- 变量命名规范:修改变量名使其语义更清晰,符合C#编码规范。
内容的提问来源于stack exchange,提问作者Rohan
相关产品推荐
相关产品推荐

