You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Unity协程执行yield return new WaitForSeconds(.01f)后后续代码不运行如何解决

问题根因

调用SceneManager.LoadScene加载新场景时,Unity默认会销毁当前场景中所有的GameObject,启动Exiting协程的宿主对象也会被一同销毁,协程会随对象销毁而中断,因此yield return之后的逻辑不会执行。
你设置的0.01秒固定等待也存在风险:不同设备的场景加载耗时不同,固定等待时间无法保证场景加载完成后再执行传送逻辑,容易出现空引用、传送失效的问题。

可行解决方案

方案1:标记协程宿主对象为跨场景不销毁

在加载场景前调用DontDestroyOnLoad,让挂载当前脚本的对象不会随场景加载被销毁,保证协程可以执行完全部逻辑,同时用异步加载代替固定时间等待,适配不同设备性能。
修正后的代码如下:

private IEnumerator Exiting()
{
    // 标记当前对象为跨场景留存,避免被销毁
    DontDestroyOnLoad(gameObject);
    
    // 异步加载场景,等待加载完全完成后再执行后续逻辑
    AsyncOperation asyncLoad = SceneManager.LoadSceneAsync("Opening Stage");
    yield return asyncLoad;

    Debug.Log("Scene loaded, lastPos: " + myLocation.getLastPos());
    Debug.Log("After Coroutine");
    myLocation.ReturnToLastPos();

    // 如果该对象后续不需要留存,执行完逻辑后自行销毁即可
    Destroy(gameObject);
}

方案2:使用场景加载完成事件回调

也可以通过监听Unity的场景加载完成事件执行传送逻辑,不需要依赖当前协程的生命周期:

private void StartExiting()
{
    // 绑定场景加载完成事件
    SceneManager.sceneLoaded += OnSceneLoaded;
    SceneManager.LoadScene("Opening Stage");
}

private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
    // 校验加载的是目标场景再执行逻辑
    if (scene.name == "Opening Stage")
    {
        // 用完后解绑事件避免重复触发
        SceneManager.sceneLoaded -= OnSceneLoaded;
        
        Debug.Log("Scene loaded, lastPos: " + myLocation.getLastPos());
        Debug.Log("After Coroutine");
        myLocation.ReturnToLastPos();
    }
}
注意事项

如果myLocation是当前场景挂载的组件,也需要对其所在的GameObject执行DontDestroyOnLoad标记,否则新场景加载后该对象会被销毁,调用getLastPos、ReturnToLastPos时会触发空引用报错。

内容的提问来源于stack exchange,提问作者memeaste

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 09:51:03