Unity协程未执行问题:生成的splash对象无法销毁
问题分析与解决方案
核心问题是启动协程的 GameObject 被提前销毁了。你在调用StartCoroutine(DestroySplash(_splashObj))之后立刻执行了Destroy(gameObject);,而Unity的协程依附于承载它的MonoBehaviour所在的GameObject——一旦这个GameObject被销毁,协程会直接终止,不会执行yield return之后的代码,所以控制台不会输出"DestroySplash",splash对象也无法被销毁。
以下是几种可行的解决方案:
方案一:将自身销毁逻辑移到协程内,等splash对象销毁后再销毁自身
修改代码如下:public GameObject splashObjPrefab; // 假设这段代码在某个方法内(如OnCollisionEnter或自定义方法) if (splash) { GameObject _splashObj = Instantiate(splashObjPrefab, this.transform.position, Quaternion.identity); _splashObj.transform.localScale = new Vector3(splashRange * 2, splashRange * 2, 1); StartCoroutine(DestroySplashThenSelf(_splashObj)); Debug.Log("Run Coroutine"); } private IEnumerator DestroySplashThenSelf(GameObject _splashObj) { yield return new WaitForSeconds(0.2f); Debug.Log("DestroySplash"); Destroy(_splashObj); // 等splash销毁后再销毁自身 Destroy(gameObject); }方案二:让splash预制体自行处理销毁逻辑
给splashObjPrefab添加一个简单的脚本:public class AutoDestroy : MonoBehaviour { public float destroyDelay = 0.2f; void Start() { Destroy(gameObject, destroyDelay); } }原脚本无需再启动协程,直接生成即可,自身销毁逻辑可保留:
public GameObject splashObjPrefab; if (splash) { GameObject _splashObj = Instantiate(splashObjPrefab, this.transform.position, Quaternion.identity); _splashObj.transform.localScale = new Vector3(splashRange * 2, splashRange * 2, 1); Debug.Log("Splash object spawned"); } Destroy(gameObject);方案三:延迟销毁自身,给协程留足执行时间
把Destroy(gameObject);改成延迟销毁,确保协程能执行完毕:public GameObject splashObjPrefab; if (splash) { GameObject _splashObj = Instantiate(splashObjPrefab, this.transform.position, Quaternion.identity); _splashObj.transform.localScale = new Vector3(splashRange * 2, splashRange * 2, 1); StartCoroutine(DestroySplash(_splashObj)); Debug.Log("Run Coroutine"); } // 延迟0.2秒以上销毁自身,让协程执行完毕 Destroy(gameObject, 0.3f);
内容的提问来源于stack exchange,提问作者SJC
相关产品推荐
相关产品推荐

