Unity3D 泛型单例
单例模式
单例模式是一种创建型设计模式,能够保证一个类只有一个实例,提供访问实例的全局节点。
通常会把一些管理类设置成单例,例如 GameManager
、UIManager
等,可以很方便地使用这些管理类单例,存储变量和调用接口。
手动挂载的泛型单例
创建 SingletonMono.cs
脚本,在类名后面添加泛型和约束,定义泛型变量,并且在 Awake
方法中对变量进行赋值。
这里的 Awake
方法是虚方法,当有管理类继承这个 SingletonMono
时,可以重写 Awake
方法进行额外的操作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| using System.Collections; using System.Collections.Generic; using UnityEngine;
public class SingletonMono<T> : MonoBehaviour where T : MonoBehaviour { static T instance; public static T Instance { get { return instance; } }
protected virtual void Awake() { if (instance == null) { instance = this as T; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); } } }
|
创建 GameManager.cs
脚本,继承 SingletonMono
这个类。
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.Collections; using System.Collections.Generic; using UnityEngine;
public class GameManager : SingletonMono<GameManager> { public int score;
protected override void Awake() { base.Awake(); score = 0; }
void Start() { }
void Update() { } }
|
在场景中创建游戏物体,把 GameManager
脚本手动挂载到游戏物体上。

创建 SingletonTest.cs
脚本,简单使用一下 GameManager.Instance
单例的变量。
1 2 3 4 5 6 7 8 9 10 11 12
| using System.Collections; using System.Collections.Generic; using UnityEngine;
public class SingletonTest : MonoBehaviour { void Start() { int score = GameManager.Instance.score; Debug.Log($"score = {score}"); } }
|
运行游戏,可以看到 GameManager
在 DontDestroyOnLoad
场景中,可以获取到 score
变量进行打印。

自动挂载的泛型单例
创建 SingletonMonoAuto.cs
脚本,在类名后面添加泛型和约束,定义泛型变量。
因为它并不需要在场景中手动创建游戏物体,也不会通过 Awake
方法对变量进行赋值。
所以在获取 Instance 属性时,如果属性为空,就通过代码创建一个不会销毁的游戏物体,并自动挂载单例组件。
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
| using System.Collections; using System.Collections.Generic; using UnityEngine;
public class SingletonMonoAuto<T> : MonoBehaviour where T : MonoBehaviour { static T instance;
public static T Instance { get { if (instance == null) { GameObject obj = new GameObject(); obj.name = typeof(T).ToString(); instance = obj.AddComponent<T>(); DontDestroyOnLoad(obj); } return instance; } } }
|
创建一个 UIManager.cs
脚本,继承 SingletonMonoAuto
这个类。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| using System.Collections; using System.Collections.Generic; using UnityEngine;
public class UIManager : SingletonMonoAuto<UIManager> { void Awake() { Debug.Log("初始化 UIManager"); }
void Start() { }
void Update() { } }
|
在 SingletonTest.cs
脚本,简单使用一下 UIManager.Instance
单例。
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| using System.Collections; using System.Collections.Generic; using UnityEngine;
public class SingletonTest : MonoBehaviour { void Start() { int score = GameManager.Instance.score; Debug.Log($"score = {score}");
UIManager uiManager = UIManager.Instance; } }
|
运行游戏,可以看到 UIManager
在 DontDestroyOnLoad
场景中自动创建。
