You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 15:14:05