单例在Unity是老生常谈的一个设计模式,并不是它有多么伟大,而是它有多么的方便,当然方便不等于滥用,我们要区分单例用的场合。在我的设计中,大多用来作为管理类,以下两个模板皆来自前辈们的手笔,部分为自己修改。
1.普通类的单例模板
public ClassSigleton<T> where T :Class
{
private static T _instance;
/// <summary>
/// 添加一个锁,防止多线程造成的多个实例,并加入私有构造函数
/// </summary>
private static readonly object syncRoot = new object();
public static readonly Type[] EmptyTypes = new Type[0];
public static T instance
{
get
{
if (_instance == null)
{
lock (syncRoot)
{
if (_instance == null)
{
ConstructorInfo ci = typeof(T).GetConstructor(BindingFlags.NonPublic | BindingFlags.Instance, null, EmptyTypes, null);
if (ci == null)
{
throw new InvalidOperationException("class must contain a private constructor");
}
_instance = (T)ci.Invoke(null);
}
}
}
return _instance;
}
}
}
2.基于MonoBehaviour
/// <summary>
/// MonoBehaviour单利模板类
/// 一定不要在Destroy函数中直接访问单例模式,非要使用实现判断instance是否存在
/// </summary>
public class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
private static T _instance;
public Transform cacheTransform
{
get;
protected set;
}
public GameObject cacheGameObject
{
get;
protected set;
}
/// <summary>
/// 添加一个锁,防止多线程造成的多个实例,并加入私有构造函数
/// </summary>
private static readonly object syncRoot = new object();
public static T instance
{
get
{
if (_instance == null)
{
lock (syncRoot)
{
if (_instance == null)
{
_instance = GameObject.FindObjectOfType(typeof(T)) as T;
if (_instance == null)
{
GameObject coreGameObject = new GameObject(typeof(T).Name);
_instance = coreGameObject.AddComponent<T>();
DontDestroyOnLoad(coreGameObject);
}
}
}
}
return _instance;
}
}
protected virtual void Awake()
{
cacheTransform = transform;
cacheGameObject = gameObject;
}
protected virtual void Destroy()
{
_instance = null;
}
}