Skip to content

Instantly share code, notes, and snippets.

@Aaron8052
Last active February 22, 2023 04:13
Show Gist options
  • Save Aaron8052/c888d5c4c2fcf1ccffc99589d5de39c6 to your computer and use it in GitHub Desktop.
Save Aaron8052/c888d5c4c2fcf1ccffc99589d5de39c6 to your computer and use it in GitHub Desktop.
MonoBehaviour Singleton (单例)

使用方法

  • 把想要实现单例的 MonoBahaviour 脚本继承MonoBehaviourSingleton

public class ExampleInstance : MonoBehaviourSingleton<ExampleInstance>

  • 之后只需要在其他代码中调用 ExampleInstance.Instance 即可

此脚本包含两个版本

Version 1

  • 单例对象生命周期开始时会对instance赋值,如果已经存在另一个instance,则会直接Destroy这个多余的实例
  • 由于此操作需要在 Awake() 中完成,因此单独开放一个 OnAwake() 的虚方法用于子类继承
  • 使用此版本可以保证当前游戏中永远只有一个实例

Version 2

  • 相比于前一个版本,此版本在没有instance的情况下会自动创建一个新的instance
  • 优点是不会占用子类中的 Awake() 方法
  • 缺点是无法保证场景中只有一个instance

可以视情况选择

using UnityEngine;
/// <summary>
/// 单例
/// </summary>
/// <typeparam name="T">类型</typeparam>
public class MonoBehaviourSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
protected static T instance;
public static T Instance => instance;
void Awake()
{
if (instance)
Destroy(gameObject);
else
instance = GetComponent<T>();
OnAwake();
}
protected virtual void OnAwake(){}
}
using UnityEngine;
/// <summary>
/// 单例
/// </summary>
/// <typeparam name="T">类型</typeparam>
public class MonoBehaviourSingleton<T> : MonoBehaviour where T : MonoBehaviour
{
protected static T instance;
public static T Instance => instance ??= FindObjectOfType<T>() ?? NewInstance();
static T NewInstance()
{
var typeName = typeof(T).Name;
var instance = new GameObject($"[Instance] {typeName}").AddComponent<T>();
Debug.LogFormat(instance, "Creating instance of <b>{0}</b>", typeName);
DontDestroyOnLoad(instance);
return instance;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment