Unity协程异常:yield return new WaitForSeconds后代码未执行
yield return new WaitForSeconds后代码未执行的排查与解决 问题现象
按照Unity Learn教程实现协程生成立方体时,点击难度按钮后,协程SpawnTarget中yield return new WaitForSeconds(spawnRate)之后的代码完全未执行。日志仅输出到:
Easy Button was clicked hop ordayım isGameActive: True Sonunda burdayım geldim
等待超过设定的1秒后,没有Buraya da geldim等后续日志,立方体也未生成。
排查与解决步骤
1. 检查时间缩放(Time.timeScale)是否为0
WaitForSeconds的计时依赖Unity的时间缩放值,如果Time.timeScale = 0,等待会永远不会结束。新手常犯的错误是在菜单场景中设置了暂停时间,启动游戏时未恢复。
修复方法:在GameManager的StartGame方法中添加时间重置代码:
public void StartGame() { isGameActive = true; Time.timeScale = 1f; // 恢复正常时间流动 StartCoroutine(SpawnTarget()); Debug.Log("geldim"); UpdateScore(0); }
2. 确认GameManager对象未被销毁/禁用
如果协程所在的GameManager GameObject被意外销毁或禁用,协程会直接终止,无法执行yield之后的代码。
验证方法:在SpawnTarget的循环中添加对象状态日志:
IEnumerator SpawnTarget() { Debug.Log("hop ordayım"); Debug.Log("isGameActive: " + isGameActive); while (isGameActive) { // 输出对象激活状态,排查是否被禁用/销毁 Debug.Log("GameManager active: " + gameObject.activeSelf + ", isGameActive: " + isGameActive); Debug.Log("Sonunda burdayım"); yield return new WaitForSeconds(spawnRate); Debug.Log("Buraya da geldim"); int index = Random.Range(0 ,targets.Count); Debug.Log("Buraya da"); Instantiate(targets[index]); Debug.Log("cok sukur be"); } }
运行后查看日志,如果GameManager active为false,需要在Hierarchy面板中确保Game Manager对象始终处于激活状态,且没有其他代码调用Destroy(this.gameObject)销毁它。
3. 排查是否意外触发了GameOver
如果有其他代码误调用了GameOver方法,isGameActive会被设为false,协程的while循环会直接退出,导致后续代码不执行。
验证方法:在GameOver方法中添加日志:
public void GameOver() { Debug.Log("GameOver方法被调用!"); gameOverText.gameObject.SetActive(true); restartButton.gameObject.SetActive(true); isGameActive = false; }
如果日志中出现GameOver方法被调用!,说明有代码意外触发了游戏结束逻辑,需要找到并修复该代码。
4. 修复代码冗余(非直接原因,但优化规范)
GameManager脚本中重复引用了using System.Collections;,删掉其中一行即可:
// 删除重复的引用 using System.Collections; // using System.Collections; 删掉这行 using UnityEngine; using TMPro; using UnityEngine.SocialPlatforms.Impl; using UnityEngine.SceneManagement; using UnityEngine.UI; using System.Runtime.CompilerServices;
内容的提问来源于stack exchange,提问作者Ata Uygur

