Unity重载场景时游戏卡住,存在不明DontDestroyOnLoad对象
Unity 场景重载卡死问题排查指南
核心问题对应
当前出现的「仅暂停按钮可响应、其余游戏功能完全停转、场景重载卡住」的问题,90%以上和两类逻辑错误相关:
- 暂停状态未正确重置,导致
Time.timeScale一直停留在暂停时的0值,游戏内所有依赖时间缩放的逻辑、异步加载流程都会被阻塞,但UGUI的按钮事件系统不受timeScale影响,所以依然可以响应点击 - 误调用
DontDestroyOnLoad生成了重复的跨场景对象,两个同功能对象的逻辑互相阻塞,甚至残留的暂停状态判断逻辑会一直认为游戏处于暂停状态,阻断所有游戏流程
分步排查操作
- 快速定位残留的跨场景对象:在Play模式下暂停运行,在Hierarchy窗口的搜索栏输入
DontDestroyOnLoad,就能直接展开所有跨场景存活的对象列表,逐一点击查看挂载的脚本,重点核对最近为暂停、重启功能新加的代码 - 检查重启按钮的执行逻辑:正确的重启流程必须在触发场景重载前,先重置暂停状态,核心逻辑顺序参考:
// 重启按钮点击逻辑 public void OnRestartLevelClick() { // 第一步:先重置时间缩放,解除暂停状态 Time.timeScale = 1; // 第二步:重置游戏内的暂停标记 GameManager.Instance.IsPaused = false; // 第三步:再执行场景重载 SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex); } - 排查单例类的初始化漏洞:所有需要跨场景存活的单例脚本,必须在
Awake方法里加上重复判空逻辑,避免场景重载时生成多份重复对象:private void Awake() { if (Instance != null && Instance != this) { Destroy(gameObject); return; } Instance = this; DontDestroyOnLoad(gameObject); } - 验证异步场景加载的逻辑:如果用了异步接口
LoadSceneAsync,要检查有没有误将allowSceneActivation设为false后,忘记在加载完成后改回true,导致场景永远卡在等待激活的状态
快速验证技巧
在重启按钮的点击事件最开头加一行临时调试代码,运行时查看控制台输出:Debug.Log("当前DontDestroyOnLoad域内的对象数量:" + UnityEngine.SceneManagement.SceneManager.GetSceneByName("DontDestroyOnLoad").GetRootGameObjects().Length);
对比正常运行状态下的数值,多出来的对象就是导致卡死的根源。
内容的提问来源于stack exchange,提问作者Malik Nouman
相关产品推荐
相关产品推荐

