Unity单例模式
单例模式通常用于生成单一管理者,例如假设游戏只能有一个玩家,那么就可以将玩家的控制器作为一个单例存在使用。或者场景控制,也可以作为一个单例来使用。
//BaseManager.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Singleton <T> where T:new()
{
private static T instance;
public static T GetInstance()
{
if(instance == null)
instance = new T();
return instance;
}
}
public class MonoSingleton<T> : MonoBehaviour where T: MonoBehaviour
{
protected static T instance;
public static T GetInstance()
{
if(instance == null)
{
instance = (T)FindFirstObjectByType(typeof(T));
if(instance == null)
{
GameObject singleton = new GameObject();
instance = singleton.AddComponent<T>();
singleton.name = typeof(T).Name;
DontDestroyOnLoad(singleton);
}
}
return instance;
}
void Awake()
{
DontDestroyOnLoad(gameObject);
if(instance == null)
instance = this as T;
else
Destroy(gameObject);
}
}
逐步解释
public class Singleton<T> where T:new()
//使用<T>来扩大其泛用性,这样就可以直接利用这个基类建立其他单例。
//where T:new()做约束,强制要求其存在新建方法,否则后续instance = new T();无效
{
private static T instance;
//单例不应该被随意获取,保持为私有状态
public static T GetInstance()
//使用一个公有函数来对单例进行访问
{
if(instance == null)//单例为空
instance = new T();//新建单例
return instance;//返回单例,由于前面已经保证单例不为空,所以必有返回值
}
}
//对于需要继承MonoBehaviour的单例,则会有一定的变化
public class MonoSingleton<T> : MonoBehaviour where T: MonoBehaviour
{
protected static T instance;
public static T GetInstance()
{
//检查单例是否为空
if(instance == null)
{
//是空的,那就先在列表里找找,原代码是FindObjectOfType,但是因为是[Obsolete]
//然后我不想看到一个warning搁那挂着(笑)所以就换成了FindFirstObjectByType
instance = (T)FindFirstObjectByType(typeof(T));
//还找不到的话就给他现做一个
if(instance == null)
{
GameObject singleton = new GameObject();
instance = singleton.AddComponent<T>();
singleton.name = typeof(T).Name;
DontDestroyOnLoad(singleton);
}
}
return instance;
}
void Awake()
{
//单例不应该被摧毁
DontDestroyOnLoad(gameObject);
if(instance == null)
instance = this as T;
//如果存在多重单例,那就销毁其他单例
else
Destroy(gameObject);
}
}