手动挂载式继承MonoBehaviour单例模式基类(不推荐)和自动挂载式继承MonoBehaviour单例模式基类(推荐)
一、手动挂载式继承MonoBehaviour单例模式基类(不推荐)
1. 特点
- 需要手动将脚本挂载到场景物体上
- 依赖 Awake 初始化
instance
- 容易破坏单例唯一性
2. 潜在问题
- 重复挂载
- 手动挂载多个脚本
- 场景切换后,场景里已有挂载对象,可能生成新的实例
- 代码动态添加多个该脚本也会破坏单例
- 构造函数与多线程
- MonoBehaviour 不允许
new 创建实例,不存在公共构造函数破坏问题
- 通常不涉及多线程,可忽略
3. 使用示例
using UnityEngine;
public class SingletonMono<T> : MonoBehaviour where T : MonoBehaviour
{private static T instance;public static T Instance => instance;protected virtual void Awake(){instance = this as T; // 必须在 Awake 中初始化}
}
4. 总结
- 优点:实现简单,直接挂在场景物体上
- 缺点:容易破坏单例唯一性,不适合大部分项目
- 推荐度:❌ 不推荐
二、自动挂载式继承MonoBehaviour单例模式基类(推荐)
1. 特点
- 无需手动挂载脚本
- 在第一次访问
Instance 时自动创建物体并挂载脚本
- 保证单例唯一性
- 支持跨场景持久化(
DontDestroyOnLoad)
2. 潜在问题
- 重复挂载问题
- 仅在自动创建物体时可能重复挂载
- 可通过逻辑保证唯一性
- 构造函数与多线程
- 同样不需要担心
new 构造函数问题
- Unity 主线程环境,通常不涉及多线程
3. 使用示例
using UnityEngine;
public class SingletonAutoMono<T> : MonoBehaviour where T : MonoBehaviour
{private static T instance;public static T Instance{get{if (instance == null){// 动态创建物体GameObject obj = new GameObject(typeof(T).Name);// 为物体添加脚本instance = obj.AddComponent<T>();// 场景切换不销毁DontDestroyOnLoad(obj);}return instance;}}
}