Unity中的单例模式

写在前面

单例模式在Unity中是一种非常常用的方式,和传统单例不同,在Unity中针对不同的情况可分为以下几种方式:heart: 。

87590528_p0

普通单例

  • 适用于普通的Mono类。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
namespace singleton
{
/// <summary>
/// 单例
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class Singleton<T> where T : new()
{
private static T _instance;

public static T Instance
{
get
{
if (_instance!=null)
{
return _instance;
}
_instance=new T();
return _instance;
}
}
}
}

单例管理器

  • 适用于继承自Mono的类。
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
39
40
using UnityEngine;

namespace singleton
{
/// <summary>
/// 单例管理器
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class SingletonManager<T> : MonoBehaviour where T : MonoBehaviour
{
private static T _instance;
public static T Instance
{
get
{

if (_instance != null) return _instance;
//在场景中寻找是否已经存在相同的管理器
var go= GameObject.Find(typeof(T) + "").GetComponent<T>();
if (go!=null)
{
_instance = go;
return _instance;
}
var ins = new GameObject(typeof(T)+"");
_instance = ins.AddComponent<T>();
Debug.Log($"创建 {typeof(T)} ");
return _instance;

}
private set { }
}

protected virtual void Awake()
{
//防止加载场景销毁
DontDestroyOnLoad(gameObject);
}
}
}

单例ScriptableObject

  • 适用于ScriptableObject 单例数据存储
  • 需要放置在Resource目录下用于读取
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
using System.Linq;
using UnityEngine;

namespace singleton
{
/// <summary>
/// So单例
/// </summary>
/// <typeparam name="T"></typeparam>
public abstract class SingletonSoManager<T> : ScriptableObject where T : Object
{
private static T _instance;

public static T Instance
{
get
{
if (_instance!=null)
{
return _instance;
}

var ins= Resources.FindObjectsOfTypeAll<T>().FirstOrDefault();
if (!ins)
{
Debug.LogError(nameof(T)+" 不存在!!");
return null;
}

_instance = ins;
return _instance;
}

}
}
}