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

Unity多对象DontDestroyOnLoad异常:单对象生效,多对象时先创对象被销毁

支持多对象的DontDestroyOnLoad单例实现

你遇到的问题是因为原脚本是全局唯一单例,所有挂载该脚本的对象会共用同一个实例标记,导致新对象加载时会销毁旧的全局实例。要实现多个对象各自保留且不重复创建,需要为每个对象类型单独维护单例。

下面是基于泛型的通用解决方案,每个需要持久化的对象可以继承这个基类,互相独立不干扰:

using UnityEngine;

public class PersistentSingleton<T> : MonoBehaviour where T : Component
{
    private static T _instance;

    public static T Instance
    {
        get
        {
            if (_instance == null)
            {
                _instance = FindObjectOfType<T>();
                if (_instance == null)
                {
                    GameObject obj = new GameObject();
                    obj.name = typeof(T).Name;
                    _instance = obj.AddComponent<T>();
                }
            }
            return _instance;
        }
    }

    protected virtual void Awake()
    {
        if (_instance == null)
        {
            _instance = this as T;
            DontDestroyOnLoad(gameObject);
        }
        else
        {
            if (this != _instance)
            {
                Destroy(gameObject);
            }
        }
    }
}

使用步骤

  • 为每个需要持久化的对象创建专属脚本,继承自上述泛型基类:
    // 音乐管理器示例
    public class MusicManager : PersistentSingleton<MusicManager>
    {
        // 在这里编写音乐控制逻辑
    }
    
    // 游戏数据管理器示例
    public class GameDataManager : PersistentSingleton<GameDataManager>
    {
        // 在这里编写数据存储/读取逻辑
    }
    
  • 将这些专属脚本分别挂载到对应的GameObject上,切换场景时每个对象都会被保留,且不会重复创建。

核心逻辑

  • 泛型类PersistentSingleton<T>会为每个不同的T(即每个子类)维护独立的静态实例变量,不同类型的对象之间完全隔离。
  • 场景加载时,脚本会先检查当前类型是否已有实例:
    • 无实例则将自身设为实例并标记DontDestroyOnLoad
    • 已有实例则销毁当前重复对象

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 02:16:13