Unity 2019 C#:物品箱设为Inactive后重生协程报错求助
问题解决思路
报错原因
你先把物品箱设为Inactive,再调用StartCoroutine启动重生协程——Unity不允许在非激活的GameObject上启动协程,这就是报错的直接原因。
两种解决方案
方案一:复用原物品箱(激活而非生成新实例)
调整代码执行顺序,先启动协程,再禁用物品箱,协程启动后会继续执行,直到时间到了再激活原物体:
public float respawnTime = 5f; // 记得在Inspector面板设置重生延迟时间 private void OnCollisionEnter(Collision other) { if (other.gameObject.CompareTag("Player")) // 用CompareTag比直接判断tag更高效,无GC { // 先启动协程,此时物体还处于激活状态,能正常启动协程 StartCoroutine(RespawnCoroutine()); // 再禁用物品箱 gameObject.SetActive(false); } } IEnumerator RespawnCoroutine() { yield return new WaitForSeconds(respawnTime); // 时间到后激活原物品箱 gameObject.SetActive(true); }
方案二:生成新的物品箱(适合需要销毁原物体的场景)
如果需要生成新的物品箱实例,建议把重生逻辑放到一个持久激活的管理器物体上(比如创建一个空物体命名为RespawnManager),避免依赖物品箱自身的激活状态:
1. 管理器脚本(挂载在RespawnManager上)
public class RespawnManager : MonoBehaviour { public static RespawnManager Instance; public GameObject itemBoxPrefab; public float respawnTime = 5f; private void Awake() { Instance = this; // 单例模式,方便其他脚本调用 } public void SpawnItemBoxAtPosition(Vector3 spawnPos, Quaternion spawnRot) { StartCoroutine(SpawnAfterDelay(spawnPos, spawnRot)); } IEnumerator SpawnAfterDelay(Vector3 pos, Quaternion rot) { yield return new WaitForSeconds(respawnTime); Instantiate(itemBoxPrefab, pos, rot); } }
2. 物品箱脚本修改
private void OnCollisionEnter(Collision other) { if (other.gameObject.CompareTag("Player")) { // 通知管理器在当前位置生成新箱子 RespawnManager.Instance.SpawnItemBoxAtPosition(transform.position, transform.rotation); // 禁用或销毁原物品箱 gameObject.SetActive(false); // 如果需要销毁原物体,替换为 Destroy(gameObject); } }
额外优化点
- 合并了你代码中重复的
if (other.gameObject.tag == "Player")判断,减少冗余 - 使用
CompareTag替代直接访问tag属性,避免不必要的GC开销
内容的提问来源于stack exchange,提问作者Make this year better
相关产品推荐
相关产品推荐

