Unity加载新场景后脚本无法访问Game Manager报空引用错误如何解决
问题根因
- 脚本执行顺序冲突:Unity默认脚本执行顺序无序,你未设置GameManager的优先级,导致新场景内的业务脚本
Awake执行时机早于GameManager的初始化逻辑,访问GameManager.instance时实例还未完成赋值。 - 单例实现不健壮:当前单例仅在
Awake时赋值,若运行上下文中不存在已初始化的GameManager实例(比如首次加载的场景没有放置GameManager、或者实例被误销毁),访问时就会返回空引用。 - 异步加载时序问题:你使用的
LoadSceneAsync是异步加载接口,若在调用加载后立刻访问新场景内的逻辑,可能场景还未完成加载,此时新场景脚本的依赖还未准备完成。
修复方案
1. 完善GameManager单例逻辑
改为带自动校验、自动创建的属性实现,避免空引用:
using UnityEngine; using UnityEngine.SceneManagement; public class GameManager : MonoBehaviour { private static GameManager _instance; public static GameManager instance { get { // 实例为空时先查找场景中已有的对象 if (_instance == null) { _instance = FindObjectOfType<GameManager>(); // 找不到就自动创建新实例 if (_instance == null) { GameObject gmObj = new GameObject("GameManager"); _instance = gmObj.AddComponent<GameManager>(); DontDestroyOnLoad(gmObj); } } return _instance; } } private void Awake() { // 避免重复生成实例 if (_instance == null) { _instance = this; DontDestroyOnLoad(gameObject); } else if (_instance != this) { Destroy(gameObject); } } public void Restart() { SceneManager.LoadSceneAsync(SceneManager.GetActiveScene().name); } // 你的其他业务逻辑示例 public System.Action LevelStarted; }
2. 调整脚本执行优先级
打开Unity编辑器的编辑 > 项目设置 > 脚本执行顺序面板,将GameManager脚本的执行顺序设置为负数(比如-100),保证它的初始化逻辑永远早于其他业务脚本执行。
3. 调整业务逻辑的访问时机
不要在业务脚本的Awake方法中访问GameManager的变量,改到Start方法中执行。如果需要场景加载完成后立刻触发逻辑,可以监听场景加载事件:
using UnityEngine; using UnityEngine.SceneManagement; public class YourBusinessScript : MonoBehaviour { private void OnEnable() { SceneManager.sceneLoaded += OnSceneLoadComplete; } private void OnDisable() { SceneManager.sceneLoaded -= OnSceneLoadComplete; } private void OnSceneLoadComplete(Scene scene, LoadSceneMode mode) { // 场景加载完成后再访问GameManager GameManager.instance.LevelStarted?.Invoke(); } }
4. 场景配置优化
不要将GameManager预制体放在可重复加载的业务场景中,统一放在初始启动场景中,或者完全依赖单例的自动创建逻辑,避免重复生成冗余实例。
内容的提问来源于stack exchange,提问作者bark
相关产品推荐
相关产品推荐

