> 文章列表 > Tengine游戏框架之单例模式

Tengine游戏框架之单例模式

Tengine游戏框架之单例模式

using UnityEngine;namespace TEngine.Runtime
{/// <summary>/// 具备Unity完整生命周期的单例/// </summary>/// <typeparam name="T"></typeparam>public class UnitySingleton<T> : MonoBehaviour,IUpdateSystem where T : MonoBehaviour{private static T _instance;/// <summary>/// 单例/// </summary>public static T Instance{get{if (_instance == null){var ins = UnityEngine.Object.FindObjectOfType<T>();if (ins != null){ins.gameObject.name = typeof(T).Name;_instance = ins;SingletonMgr.Retain(ins.gameObject);return Instance;}System.Type thisType = typeof(T);string instName = thisType.Name;GameObject go = SingletonMgr.GetGameObject(instName);if (go == null){go = GameObject.Find($"{instName}");if (go == null){go = new GameObject(instName);go.transform.position = Vector3.zero;}}_instance = go.GetComponent<T>();if (_instance == null){_instance = go.AddComponent<T>();}if (_instance == null){TLogger.LogError($"Can't create UnitySingleton<{typeof(T)}>");}}return _instance;}}/// <summary>/// 单例对象获取/// </summary>/// <returns></returns>public static T Active(){return Instance;}/// <summary>/// 单例是否有效/// </summary>public static bool IsValid{get{return _instance != null;}}/// <summary>/// 检查单例/// </summary>/// <returns></returns>private bool CheckInstance(){if (this == Instance){return true;}GameObject.Destroy(gameObject);return false;}/// <summary>/// 加载/// </summary>protected virtual void OnLoad(){}/// <summary>/// 初始化/// </summary>public virtual void Awake(){if (CheckInstance()){UpdateInstance.Instance.Retain(this);OnLoad();}
#if UNITY_EDITORTLogger.LogInfo($"UnitySingleton Instance:{typeof(T).Name}");
#endifGameObject tEngine = SingletonMgr.Root;if (tEngine != null){this.gameObject.transform.SetParent(tEngine.transform);}}/// <summary>/// 获取游戏框架模块优先级。实现Interface/// </summary>/// <returns></returns>/// <remarks>优先级较高的模块会优先轮询,并且关闭操作会后进行。</remarks>public int GetPriority(){return Priority;}/// <summary>/// 获取游戏框架模块优先级。/// </summary>/// <remarks>优先级较高的模块会优先轮询,并且关闭操作会后进行。</remarks>public virtual int Priority{get{return 1;}}/// <summary>/// OnUpdate通过TEngine统一驱动,舍弃Unity的Update/// </summary>/// <param name="elapseSeconds"></param>/// <param name="realElapseSeconds"></param>public virtual void OnUpdate(float elapseSeconds, float realElapseSeconds){}/// <summary>/// 单例销毁/// </summary>public virtual void OnDestroy(){UpdateInstance.Instance.Release(this);Release();}/// <summary>/// 单例释放/// </summary>public static void Release(){if (_instance != null){SingletonMgr.Release(_instance.gameObject);_instance = null;}}}
}

上面是MonoBehavior单例游戏对象脚本;

    /// <summary>/// 单例接口/// </summary>public interface ISingleton{/// <summary>/// 激活/// </summary>void Active();/// <summary>/// 释放/// </summary>void Release();}    /// <summary>/// 全局单例对象(非线程安全)/// </summary>/// <typeparam name="T"></typeparam>public abstract class TSingleton<T> : ISingleton where T : TSingleton<T>, new(){protected static T _instance = default(T);/// <summary>/// 单例对象/// </summary>public static T Instance{get{if (null == _instance){_instance = new T();_instance.Init();
#if UNITY_EDITORTLogger.LogInfo($"TSingleton Instance:{typeof(T).Name}");
#endifSingletonMgr.Retain(_instance);}return _instance;}}/// <summary>/// 是否有效/// </summary>public static bool IsValid{get{return _instance != null;}}protected TSingleton(){}/// <summary>/// 初始化/// </summary>protected virtual void Init(){}/// <summary>/// 激活/// </summary>public virtual void Active(){}/// <summary>/// 单例释放/// </summary>public virtual void Release(){if (_instance != null){SingletonMgr.Release(_instance);_instance = null;}}}

上面是普通的单例对象脚本。

/// <summary>/// 单例管理器(统一化持久和释放)/// </summary>public static class SingletonMgr{/// <summary>/// 单例对象列表/// </summary>private static List<ISingleton> _iSingletonList;/// <summary>/// 单例游戏对象字典/// </summary>private static Dictionary<string, GameObject> _gameObjects;private static GameObject _root;/// <summary>/// 单例游戏对象的父级/// </summary>public static GameObject Root{get{if (_root == null){_root = GameObject.Find("TEngineMgr");if (_root == null){_root = new GameObject("TEngineMgr");_root.transform.position = Vector3.zero;}UnityEngine.Object.DontDestroyOnLoad(_root);}return _root;}}/// <summary>/// 单例对象注册/// </summary>/// <param name="go"></param>public static void Retain(ISingleton go){if (_iSingletonList == null){_iSingletonList = new List<ISingleton>();}_iSingletonList.Add(go);}/// <summary>/// 单例游戏对象注册/// </summary>/// <param name="go"></param>public static void Retain(GameObject go){if (_gameObjects == null){_gameObjects = new Dictionary<string, GameObject>();}if (!_gameObjects.ContainsKey(go.name)){_gameObjects.Add(go.name, go);}}/// <summary>/// 单例游戏对象释放销毁/// </summary>/// <param name="go"></param>public static void Release(GameObject go){if (_gameObjects != null && _gameObjects.ContainsKey(go.name)){_gameObjects.Remove(go.name);UnityEngine.Object.Destroy(go);}}/// <summary>/// 单例对象释放/// </summary>/// <param name="go"></param>public static void Release(ISingleton go){if (_iSingletonList != null && _iSingletonList.Contains(go)){_iSingletonList.Remove(go);}}/// <summary>/// 所有的单例释放销毁/// </summary>public static void Release(){if (_gameObjects != null){foreach (var item in _gameObjects){UnityEngine.Object.Destroy(item.Value);}_gameObjects.Clear();}if (_iSingletonList != null){for (int i = 0; i < _iSingletonList.Count; ++i){_iSingletonList[i].Release();}_iSingletonList.Clear();}Resources.UnloadUnusedAssets();}/// <summary>/// 根据名字获得单例游戏对象/// </summary>/// <param name="name"></param>/// <returns></returns>public static GameObject GetGameObject(string name){GameObject go = null;if (_gameObjects != null){_gameObjects.TryGetValue(name, out go);}return go;}/// <summary>/// 检查是否有该单例游戏对象/// </summary>/// <param name="name"></param>/// <returns></returns>internal static bool ContainsKey(string name){if (_gameObjects != null){return _gameObjects.ContainsKey(name);}return false;}/// <summary>/// 根据名字获取该单例对象/// </summary>/// <param name="name"></param>/// <returns></returns>internal static ISingleton GetSingleton(string name){for (int i = 0; i < _iSingletonList.Count; ++i){if (_iSingletonList[i].ToString() == name){return _iSingletonList[i];}}return null;}/// <summary>/// 释放所有单例【游戏重启可以使用】/// </summary>public static void ReStart(){Release();SceneManager.LoadScene(0);}}

上面是游戏中的所有单例对象,不管是普通单例或者是MonBehaviour单例的统一管理器。