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

Unity单例脚本重启编辑器后需重挂载以规避空引用异常

问题分析与解决方案

你的空引用问题根源有两个:

  • 单例逻辑不完整:当前代码仅处理了重复实例的销毁,但未确保单例对象在场景切换时不被销毁,也没处理Unity编辑器中静态变量的残留引用。
  • 编辑器静态变量残留:Unity编辑器停止运行后,静态变量不会自动清空,下次启动时Timing可能指向已销毁的对象,导致访问Bpm时报错。

修正后的单例代码

using UnityEngine;

public class Conductor : MonoBehaviour
{
    public static Conductor Timing { get; private set; }

    [SerializeField] private double bpm;

    private void Awake()
    {
        // 处理重复实例:若已有单例,销毁当前对象
        if (Timing != null)
        {
            Destroy(gameObject);
            return;
        }

        Timing = this;
        // 确保对象在场景切换时不被销毁
        DontDestroyOnLoad(gameObject);
    }

    // 对象销毁时重置静态变量,避免残留无效引用
    private void OnDestroy()
    {
        if (Timing == this)
        {
            Timing = null;
        }
    }

    // 游戏启动前重置静态变量,解决编辑器残留问题
    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
    private static void ResetSingleton()
    {
        Timing = null;
    }

    public double Bpm
    {
        get => bpm;
        set => bpm = value;
    }
}

关键修改说明

  • DontDestroyOnLoad(gameObject):让单例对象在场景切换时保留,避免因场景加载导致实例销毁,Timing变为空引用。
  • OnDestroy重置静态变量:单例对象被销毁时,将Timing置空,防止后续引用已销毁的无效对象。
  • RuntimeInitializeOnLoadMethod:在游戏启动前强制重置静态变量,解决Unity编辑器停止运行后静态变量残留的问题,确保每次启动时Timing处于初始状态。

调用注意事项

确保场景中仅存在一个挂载Conductor的游戏对象,避免重复实例被销毁的情况。调用时可额外增加空判断,防止极端场景报错:

if (Conductor.Timing != null)
{
    var currentBpm = Conductor.Timing.Bpm;
    // 后续业务逻辑
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:25:42