初学者,自用笔记
建议不单独使用单例,改为单例注册表+DI框架集中管理
懒加载单例父类模板
by B站 超级依薇尔
//支持懒加载,awake之前已有对象调用,则提前创建单例
//空对象Manager命名应与脚本相同
public class TheManager<T> : MonoBehaviour where T : MonoBehaviour
{
// 单例实例的公开访问属性
public static T Instance
{
get
{
// 若实例为空,先在场景中查找该类型的组件
if (_instance == null)
{
_instance = Object.FindAnyObjectByType<T>();
}
// 若场景中未找到实例,尝试创建
if (_instance == null)
{
Debug.Log($"单例模式 {typeof(T).Name} 场景中不存在,尝试创建...");
}
// 若仍为空,进一步处理
if (_instance == null)
{
// 查找带有 "Manager" 标签的游戏对象(用于挂载新组件)
GameObject target = GameObject.FindGameObjectWithTag("Manager");
if (target == null)
{
// 若未找到标签为 "Manager" 的对象,创建一个新的游戏对象
target = new GameObject();
target.name = $"单例模式管理器 {typeof(T).Name}"; // 命名为具体管理器名称
}
// 若成功获取或创建了目标对象,给它添加 T 类型的组件(即单例实例)
if (target != null)
{
_instance = target.AddComponent<T>();
}
}
return _instance;
}
set
{
// 若实例为空,将传入的值赋给实例(初始化)
if (_instance == null)
{
_instance = value;
}
else
{
// 若已有实例,销毁新传入的重复实例(确保单例唯一性)
if (value != null)
{
Destroy(value);
}
}
}
}
// 静态实例变量(私有,通过 Instance 属性访问)
private static T _instance;
// 唤醒时初始化单例
private void Awake()
{
Instance = this as T;
// 标记该对象在场景切换时不被销毁(确保单例跨场景存在)
DontDestroyOnLoad(_instance.gameObject);
}
}
//用例public class GameManager : Singleton<GameManager>
//调用为Manager.Instance,子类无需再次初始化

京公网安备 11010502036488号