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

Unity单例ScoreKeeper切换游戏场景时抛出NullReferenceException求助

解决调用ScoreKeeper.ResetScore时的NullReferenceException异常

关键排查点

  • 确认LevelManager调用时机
    不要在Awake()中直接调用ResetScore,场景加载时LevelManager可能比DontDestroyOnLoad的ScoreKeeper实例先完成初始化。把调用逻辑移到Start()方法,或者通过SceneManager.sceneLoaded回调触发,确保场景完全加载后再访问单例。

  • 检查单例实现的严谨性
    确保ScoreKeeper的单例代码没有逻辑漏洞,示例正确实现:

    private static ScoreKeeper _instance;
    public static ScoreKeeper Instance => _instance;
    
    void Awake()
    {
        if (_instance != null)
        {
            Destroy(gameObject);
            return;
        }
        _instance = this;
        DontDestroyOnLoad(gameObject);
    }
    

    注意:后续场景无需再放置ScoreKeeper预制体——DontDestroyOnLoad会保留第一个实例,重复放置会导致新实例被销毁,如果LevelManager引用了被销毁的场景内实例,就会触发空引用。

  • 排查ResetScore方法内部
    空引用可能来自方法内未初始化的变量(比如分数显示UI未赋值)。在方法内添加日志排查:

    public void ResetScore()
    {
        Debug.Log($"ResetScore triggered by: {gameObject.name}");
        if (scoreDisplayText == null)
        {
            Debug.LogError("scoreDisplayText未在ScoreKeeper中赋值");
            return;
        }
        // 重置分数逻辑
        currentScore = 0;
        scoreDisplayText.text = currentScore.ToString();
    }
    
  • 验证LevelManager的引用方式
    LevelManager必须通过ScoreKeeper.Instance访问单例,禁止使用FindObjectOfType<ScoreKeeper>()或场景内直接拖拽引用——后者会在场景切换后指向已销毁的实例。

快速验证步骤

  1. 在LevelManager调用ResetScore前添加日志:Debug.Log($"ScoreKeeper实例状态: {ScoreKeeper.Instance}");,确认实例不为空。
  2. 在ScoreKeeper的Awake()和OnDestroy()中添加日志,追踪实例的创建/销毁时机,对比LevelManager的调用时机是否冲突。
  3. 移除所有后续场景中的ScoreKeeper预制体,只保留初始场景(如MainMenu)中的实例,测试是否仍报错。

内容的提问来源于stack exchange,提问作者Maxence Hermand

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 03:22:10