什么是单例?
一个类有且仅有一个实例,它自行实例化并向整个系统提供这个实例。
作为最简单的设计模式之一,单例模式经常会被使用,但Unity中的写法与其他开发环境下有所不同。
要在Unity中保持一个单例,又要很方便的调用MonoBehaviour对象不报错,要对写法进行改造。
先上单例基类代码:MonoSingleton.cs
using UnityEngine;
/// <summary>
/// MonoBehaviour单例基类<br/>
/// <para>ZhangYu 2018-03-14</para>
/// <para>Blog:https://segmentfault.com/a/1190000015261387</para>
/// </summary>
public class MonoSingleton<T> : MonoBehaviour where T : MonoBehaviour {
// 单例
private static T instance;
/// <summary>获取单例</summary>
public static T GetInstance() {
if (instance == null) {
// 在已存在的脚本中查找单例
instance = (T)FindObjectOfType(typeof(T));
// 创建单例
if (instance == null) new GameObject(typeof(T).Name).AddComponent<T>();
}
return instance;
}
// 获取单例/销毁重复对象
protected virtual void Awake() {
if (instance == null) {
instance = this as T;
DontDestroyOnLoad(gameObject);
Init();
} else if (instance != this) {
if (instance.gameObject != gameObject) {
Destroy(gameObject);
} else {
Destroy(this);
}
}
}
// 重空单例
protected virtual void OnDestroy() {
if (instance == this) instance = null;
}
// 初始化
protected virtual void Init() {
}
}
用法:
自定义的单例继承Singleton并传入自己的类型。
例如:GameManager.cs
using UnityEngine;
public class GameManager : Singleton<GameManager> {
protected override void Init() {
// 在这里写自己的代码
}
}
情况1:当场景中已经存在一个GameManager,其他后出现的GameManager对象都会被销毁,保证系统中有且仅有一个实例。
情况2:当场景中无GameMananger时,会创建一个叫GameMananger的物体并附加脚本,自行实例化。
测试代码:Test.cs
using UnityEngine;
public class Test : MonoBehaviour {
private void Start () {
print(GameManager.getInstance());
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。