Unity中如何等待场景加载完成后再激活?
正确实现场景加载与激活的方案
一、同步加载场景的正确等待方式
如果使用LoadScene同步加载(LoadAdditive模式),不要在同一帧直接调用SetActiveScene——场景加载完成后需要一帧时间完成注册与初始化,可通过以下两种方式处理:
使用
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; } }用协程等待一帧
同步加载后等待一帧,确保场景完成初始化再激活: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
相关产品推荐
相关产品推荐

