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_EDITOR
            TLogger.LogInfo($"UnitySingleton Instance:{typeof(T).Name}");
#endif
            GameObject 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_EDITOR
                    TLogger.LogInfo($"TSingleton Instance:{typeof(T).Name}");
#endif
                    SingletonMgr.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单例的统一管理器。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Data菌

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值