Unity基础 —— 多场景管理与 DontDestroyOnLoad
目录
多场景管理与 DontDestroyOnLoad
在 Unity 中,默认的场景加载方式会销毁当前场景的所有对象并加载新场景。为了实现持久化的全局功能或无缝的大世界体验,需要使用多场景管理技术。
1. DontDestroyOnLoad (DDOL)
DontDestroyOnLoad 是一个方法,用于将指定的 GameObject 从当前场景移到一个特殊的 "DontDestroyOnLoad" 根节点下,使其在场景切换时不会被卸载。
- 适用对象: 全局唯一的管理器,如
AudioManager(背景音乐连续播放)、NetworkManager(保持网络连接)、DataManager(存储玩家临时状态)。 - 代码示例:
using UnityEngine; public class GlobalManager : MonoBehaviour { public static GlobalManager Instance; void Awake() { // 单例模式配合 DDOL if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); } else { // 关键点:防止重复从新场景加载导致出现多个实例 Destroy(gameObject); } } }
2. Additive 模式(叠加加载)
除了传统的 Single 模式(关闭旧的加载新的),Unity 支持使用 LoadSceneMode.Additive 模式。
-
原理: 在不销毁当前场景的前提下,将另一个场景的内容“叠加”到当前层级中。
-
应用场景:
- 大世界分块加载: 当玩家移动到某个区域时,异步加载相邻区域的场景。
- 固定背景: 一个场景专门放 UI 和核心管理器,另一个场景放具体的关卡内容。
-
代码示例:
using UnityEngine; using UnityEngine.SceneManagement; public class SceneLoader : MonoBehaviour { public void LoadLevelAdditive(string sceneName) { // 异步叠加加载 SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive); } public void UnloadLevel(string sceneName) { // 卸载不再需要的场景 SceneManager.UnloadSceneAsync(sceneName); } }
3. 主动场景 (Active Scene)
当多个场景同时存在时,Unity 会有一个 Active Scene。
- 影响: 新生成的物体会默认出现在 Active Scene 中;环境光照(Lighting Settings)和重力等物理设置也以 Active Scene 为准。
- 代码设置:
SceneManager.SetActiveScene(Scene scene);
4. 面试核心考点
- Q: DDOL 会导致内存泄漏吗?
- A: 会。如果 DDOL 的物体内部引用了大量已销毁场景中的资源(如贴图、材质),由于 DDOL 根节点一直存在,这些资源将无法被 GC 回收。
- Q: 如何处理 DDOL 物体的单例重复问题?
- A: 必须在
Awake中检查静态实例Instance。如果已存在,则Destroy(gameObject)。否则,每次回到初始场景都会多出一个管理器。
- A: 必须在
- Q: 场景加载时的 Loading 进度条怎么实现?
- A: 使用
AsyncOperation。通过AsyncOperation.progress获取 0 到 1 的加载数值,但要注意 Unity 在 0.9 时会停住(等待激活),需处理allowSceneActivation属性。
- A: 使用
- Q: 叠加加载时,两个场景有同名的 GameObject 会冲突吗?
- A: 不会冲突,它们在内存中是独立的对象。但如果脚本逻辑通过
GameObject.Find查找,可能会找错对象。建议使用特定的 Tag 或直接引用。
- A: 不会冲突,它们在内存中是独立的对象。但如果脚本逻辑通过

浙公网安备 33010602011771号