1.非组件单例
写法有很多种,记录我碰到过的写法
- 第一种方法通过反射
介绍一下几个API:
GetConstructors
获取所有构造函数
GetParameters
获取该函数所有参数
Invoke
执行元数据中方法
public class SingleTon<T> where T : SingleTon<T>
{
private static T instance = null;
public static T Instance
{
get
{
if (instance == null)
{
//获取所有 非共有的构造函数
ConstructorInfo[] ctors = typeof(T).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
//获取参数个数为0个的构造函数,即无参构造
ConstructorInfo ctor = Array.Find(ctors, (c) => c.GetParameters().Length == 0);
//Invoke执行函数
instance = ctor.Invoke(null) as T;
}
return instance;
}
}
}
- 第二种通过加约束,
new()
表示子类必须实现无参构造函数
直接调用子类构造函数
public class SingleTon<T> where T : new()
{
private static T _ins = null;
public static T Instance
{
get
{
if (_ins == null)
{
_ins = new T();
}
return _ins;
}
}
}
2.Mono单例
- API:
FindObjectOfType
按类型查找对象列表,相对应的还有FindObjectsOfType
,一个返回object
,一个返回object[]
Application.isPlaying
当前游戏是否正在运行
using UnityEngine;
public class SingleTonMono<T> : MonoBehaviour where T : SingleTonMono<T>
{
private static T instance = null;
public static T Instance
{
get
{
if (instance != null) return instance;
//先在场景中找
instance = FindObjectOfType(typeof(T)) as T;
//找不到就创建
if (instance == null)
{
var name = typeof(T).ToString();
var go = new GameObject(name);
instance = go.GetComponent<T>();
if (instance == null)
instance = go.AddComponent<T>();
}
//应用开始后就添加到不销毁结点中
if(Application.isPlaying)
DontDestroyOnLoad(instance);
return instance;
}
}
}