Unity中调用单例类方法触发NullReferenceException的问题排查与解决
Unity单例模式空引用问题排查与解决
我之前在Unity里用单例存游戏状态时也踩过一模一样的坑!先帮你理清楚整个问题:
问题现象
你尝试用Stat_player单例类存储玩家状态,但调用Stat_player.instance.Set_name(name)时控制台抛出NullReferenceException,一开始完全摸不着头脑。
你的示例代码如下:
public class Stat_player{ public static Stat_player instance; /*Unity方法*/ public void Awake(){ if(instance != null){ Debug.logError("more than one instance is in use!"); return; } else{ instance = this; } } private int hp = default; private int gold = default; private string name = default; public void Set_name(string nameP){ name = nameP; } } public class Character{ public string name = "Mark"; public void Build_character(){ Stat_player.instance.Set_name(name); } }
问题根源
核心原因很简单:你没有把Stat_player脚本挂载到任何一个GameObject上!
Unity的生命周期方法(比如Awake())只有当脚本附着在场景中激活的GameObject上时才会被执行。你的Stat_player类虽然定义了单例逻辑,但Awake()从未运行过,导致instance变量一直是null,调用它的方法自然就触发空引用异常了。
解决办法
只需要两步就能搞定:
- 在Unity编辑器里新建一个空GameObject(可以命名为
GameStateManager之类的,方便识别) - 将
Stat_player脚本拖拽挂载到这个空GameObject上,确保该GameObject在场景加载时处于激活状态
这样游戏启动时,Awake()方法会自动执行,完成instance的初始化,之后调用Stat_player.instance就能正常访问单例对象了。
额外优化建议
为了让单例更健壮,你可以修改一下单例的获取方式,就算忘了挂载脚本,也能自动创建实例(不过还是推荐手动挂载,更可控):
public class Stat_player : MonoBehaviour { public static Stat_player instance; public void Awake(){ if(instance != null){ Debug.LogError("More than one Stat_player instance exists!"); Destroy(gameObject); return; } instance = this; DontDestroyOnLoad(gameObject); // 跨场景保留单例,可选 } // 改用属性封装实例获取 public static Stat_player Instance { get { if (instance == null) { GameObject obj = new GameObject("Stat_player_Singleton"); instance = obj.AddComponent<Stat_player>(); } return instance; } } private int hp = default; private int gold = default; private string name = default; public void Set_name(string nameP){ name = nameP; } }
内容的提问来源于stack exchange,提问作者user17711032
相关产品推荐
相关产品推荐

