Unity中Coroutine与OnMouseDown实现异常:点击scoreBoost后游戏冻结求助
问题原因与解决方案
游戏冻结的根源
你写的while (scoreBonus == true)是同步死循环:当点击带scoreBoost标签的物体后,scoreBonus被设为true,主线程会被这个无限循环牢牢占用,根本没时间执行协程里的yield return new WaitForSeconds(5),导致scoreBonus永远不会变回false,游戏直接卡死。
另外还有个逻辑漏洞:如果scoreBonus是Target脚本的成员变量,每个水果实例都会有自己的scoreBonus状态,点击加成道具后,只有这个道具的scoreBonus是true,其他普通水果的加成判断根本不会生效,等于白做。
修正后的实现代码
1. 改造GameManager脚本(全局管理加成状态)
把加成状态移到全局的GameManager里,确保所有水果共享同一个加成状态:
public class GameManager : MonoBehaviour { public bool isGameActive; public bool scoreBonusActive = false; // 全局加成状态标记 // 启动分数加成的公共方法 public void ActivateScoreBonus() { if (!scoreBonusActive) // 防止重复触发 { StartCoroutine(ScoreBonusCoroutine()); } } private IEnumerator ScoreBonusCoroutine() { scoreBonusActive = true; yield return new WaitForSeconds(5); scoreBonusActive = false; } // 你的原有分数更新方法 public void UpdateScore(int points) { // 这里写你更新得分面板的逻辑 } }
2. 重写Target脚本的OnMouseDown方法
去掉死循环,改成单次条件判断,每次点击只处理一次逻辑:
public class Target : MonoBehaviour { public GameManager gameManager; public int pointValue = 1; public GameObject exposionParticle; private void OnMouseDown() { if (!gameManager.isGameActive) return; // 处理分数加成道具 if (gameObject.CompareTag("scoreBoost")) { gameManager.ActivateScoreBonus(); Destroy(gameObject); Instantiate(exposionParticle, transform.position, Quaternion.identity); return; // 道具本身不加基础分,直接结束 } // 处理普通水果,根据全局加成状态计算得分 int finalPoints = gameManager.scoreBonusActive ? pointValue + 1 : pointValue; gameManager.UpdateScore(finalPoints); Destroy(gameObject); Instantiate(exposionParticle, transform.position, Quaternion.identity); } }
修正后的逻辑说明
- 点击
scoreBoost道具时,通知GameManager启动5秒的全局加成协程,然后销毁道具、生成粒子,不额外加分。 - 点击普通水果时,先判断GameManager里的
scoreBonusActive状态:如果处于加成期,就加pointValue+1分,否则加基础分。 - 全程没有同步循环,主线程可以正常处理协程和其他游戏逻辑,不会再出现冻结问题。
内容的提问来源于stack exchange,提问作者Ruslan
相关产品推荐
相关产品推荐

