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

Unity中如何等待场景加载完成后再激活?

正确实现场景加载与激活的方案

一、同步加载场景的正确等待方式

如果使用LoadScene同步加载(LoadAdditive模式),不要在同一帧直接调用SetActiveScene——场景加载完成后需要一帧时间完成注册与初始化,可通过以下两种方式处理:

  1. 使用SceneManager.sceneLoaded回调
    注册场景加载完成的回调,在回调内执行激活操作:

    using UnityEngine.SceneManagement;
    
    void LoadAndActivateScene()
    {
        SceneManager.sceneLoaded += OnSceneLoaded;
        SceneManager.LoadScene("MyScene", LoadSceneMode.Additive);
    }
    
    void OnSceneLoaded(Scene scene, LoadSceneMode mode)
    {
        if (scene.name == "MyScene")
        {
            SceneManager.SetActiveScene(scene);
            SceneManager.sceneLoaded -= OnSceneLoaded;
        }
    }
    
  2. 用协程等待一帧
    同步加载后等待一帧,确保场景完成初始化再激活:

    using UnityEngine;
    using UnityEngine.SceneManagement;
    using System.Collections;
    
    void LoadAndActivateScene()
    {
        SceneManager.LoadScene("MyScene", LoadSceneMode.Additive);
        StartCoroutine(ActivateSceneAfterFrame("MyScene"));
    }
    
    IEnumerator ActivateSceneAfterFrame(string sceneName)
    {
        yield return null;
        Scene targetScene = SceneManager.GetSceneByName(sceneName);
        if (targetScene.isLoaded)
        {
            SceneManager.SetActiveScene(targetScene);
        }
        else
        {
            Debug.LogError($"场景 {sceneName} 加载失败");
        }
    }
    

二、异步加载场景的正确协程实现

你之前的协程问题核心是外部变量asyncLoad导致的逻辑混乱,将加载任务封装在协程内部即可解决:

using UnityEngine;
using UnityEngine.SceneManagement;
using System.Collections;

void LoadAndActivateSceneAsync()
{
    StartCoroutine(LoadAndActivateSceneCoroutine("MyScene"));
}

IEnumerator LoadAndActivateSceneCoroutine(string sceneName)
{
    // 用局部变量存储加载操作,避免外部状态干扰
    AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
    asyncLoad.allowSceneActivation = false;

    // 等待资源加载完成(Unity异步加载进度到0.9表示资源加载完毕)
    while (asyncLoad.progress < 0.9f)
    {
        Debug.Log($"加载进度: {asyncLoad.progress * 100:F1}%");
        yield return null;
    }

    Debug.Log("资源加载完成,准备激活场景");
    asyncLoad.allowSceneActivation = true;

    // 等待场景完全激活
    while (!asyncLoad.isDone)
    {
        yield return null;
    }

    // 确认场景状态后激活
    Scene targetScene = SceneManager.GetSceneByName(sceneName);
    if (targetScene.isLoaded)
    {
        SceneManager.SetActiveScene(targetScene);
        Debug.Log($"场景 {sceneName} 已成功激活");
    }
    else
    {
        Debug.LogError($"场景 {sceneName} 激活失败");
    }
}

关键修复点

  • 将AsyncOperation设为协程局部变量,避免外部重复加载的逻辑冲突
  • 移除不必要的多帧等待(除非需要做加载后的缓冲处理),allowSceneActivation = true后Unity会自动完成激活流程
  • 激活前检查场景加载状态,避免异常

额外注意事项

  • 确保场景名"MyScene"与Build Settings中添加的场景名称完全一致(大小写敏感)
  • 可通过布尔变量控制协程调用,避免重复触发:
    private bool isLoading = false;
    
    void LoadAndActivateSceneAsync()
    {
        if (!isLoading)
        {
            isLoading = true;
            StartCoroutine(LoadAndActivateSceneCoroutine("MyScene"));
        }
    }
    
    IEnumerator LoadAndActivateSceneCoroutine(string sceneName)
    {
        // ... 加载逻辑 ...
        isLoading = false;
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.11 17:43:12