Unity 单例模版

c#:使用泛型实现单例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
using System; 
using System.Collections.Generic;
using System.Text; using System.Reflection;
/// <summary> /// 1.泛型 /// 2.反射 /// 3.抽象类 /// 4.命名空间 /// </summary>
namespace QFramework
{
  public abstract class QSingleton<T> where T : QSingleton<T>
  {
    protected static T instance = null; protected QSingleton() { }
  public static T Instance()
  {
      if (instance == null)
      {
// 先获取所有非public的构造方法
ConstructorInfo[] ctors = typeof(T).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
// 从ctors中获取无参的构造方法
ConstructorInfo ctor = Array.Find(ctors, c => c.GetParameters().Length == 0);
if (ctor == null)
throw new Exception("Non-public ctor() not found!");
// 调用构造方法
instance = ctor.Invoke(null) as T;
      }
    return instance;
    }
  }
}

unity实现MonoBehaviour 单例,约束GameObject的个数,这个需求,还没有思路,只好在游戏运行时判断有多少个GameObject已经挂上了该脚本,然后如果个数大于1抛出错误即可。在脚本销毁时,把静态实例置空。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
using UnityEngine;
/// <summary> /// 需要使用Unity生命周期的单例模式 /// </summary>
namespace QFramework
{
  public abstract class QMonoSingleton<T> : MonoBehaviour where T : QMonoSingleton<T>
  {
  protected static T instance = null;
    public static T Instance()
    {
  if (instance == null)
  {
 instance = FindObjectOfType<T>();
        if (FindObjectsOfType<T>().Length > 1)
{
QPrint.FrameworkError ("More than 1!");
return instance;
        }
if (instance == null)
        {
string instanceName = typeof(T).Name; QPrint.FrameworkLog ("Instance Name: " + instanceName);
GameObject instanceGO = GameObject.Find(instanceName);
if (instanceGO == null) instanceGO = new GameObject(instanceName);
instance = instanceGO.AddComponent<T>();
DontDestroyOnLoad(instanceGO);
//保证实例不会被释放
QPrint.FrameworkLog ("Add New Singleton " + instance.name + " in Game!");
}
else {
QPrint.FrameworkLog ("Already exist: " + instance.name);
}
}
return instance;
}
  protected virtual void OnDestroy()
  {
instance = null;
  }
}