Unity中常用的三种单例模式(使用继承单例基类的方式实现)

   日期:2020-07-09     浏览:130    评论:0    
核心提示:在开发中,想必用到的最多的就是单例模式了。那么今天就分享一下我经常在开发中用到的单例模式。伪单例using UnityEngine; public class SingleScript : MonoBehaviour{ public static SingleScript Instance; private void Awake() { Instance = this; }}不继承MonoBehaviour的单例public clas

在开发中,想必用到的最多的就是单例模式了。那么今天就分享一下我经常在开发中用到的单例模式。

伪单例

using UnityEngine;
 
public class SingleScript : MonoBehaviour
{
 
    public static SingleScript Instance;
 
    private void Awake()
    {
        Instance = this;
    }
}

不继承MonoBehaviour的单例

public class SingleScriptClass
{
    public int game = 0;
    
    private static SingleScriptClass _instance;
 
    public  static SingleScriptClass Instance()
    {
        if (null == _instance)
            _instance = new SingleScriptClass();
        return _instance;
    }
}

你会发现这样写 每次新建类时都要手动写一遍 会很麻烦 有没有更简单的一劳永逸的方法呢?

当然了 我会在下面创建一个单例基类 这样每次创建的类需要使用单例模式时只需要继承该类就会具有单例模式的特点了

因为是使用了创建对象的方式 脚本其实可以不用挂载在场景物体中 (如果忘记挂载脚本)脚本在被调用时会自动创建一个物体给他挂载脚本

//创建脚本对象(立即执行Awake)
new GameObject(“Singleton of” + typeof(T).Name).AddComponent();

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Common
{
      ///<summary>
	  ///脚本单例类
	  ///</summary>
      public class MonoSingleton<T> : MonoBehaviour where T:MonoSingleton<T> 
  {
        //T 表示子类类型
        private static T instance;
        public static T Instance
        {
            get
            {
                if (instance==null)
                {
                    //在场景中根据类型查找引用
                    instance = FindObjectOfType<T>();

                    //如果忘记挂载 T这个脚本了 
                    if (instance==null)
                    {
                        //创建脚本对象(立即执行Awake)
                        new GameObject("Singleton of" + typeof(T).Name).AddComponent<T>();
                    }
                    else
                    {
                        //初始化
                        instance.Init();
                    }
                }
                return instance;
            }
        }
        /// <summary>
        /// 如果子类需要在Awake操作 重写这个方法
        /// </summary>
        public virtual void Init()
        {
            
        }

        protected void Awake()
        {
            if (instance==null)
            {
                instance = this as T;
                Init();
            }
        }

    }
}


使用方法也很简单 只需要继承该类就好


using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace CLK
{
    public class Test: Common.MonoSingleton<Test>
    {
        public void DebugTest()
        {
            Debug.Log("我是Test class");
        }
    }
}

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Common;
using System;

namespace CLK
{
    public class GameManager: MonoSingletonDontDestroy<GameManager>
    {
      //如果需要在awake方法中执行一些逻辑 可以重写Init方法
        public override void Init()
        {
            base.Init();
            //TODO:
        }
        private void Start()
        {
            Test.Instance.DebugTest();
        }
    }
}


运行结果

还有其他两种单例基类写法

一种是使用了unity的DontDestroyOnLoad方法 切换场景不会卸载物体

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

namespace Common
{
      ///<summary>
	  ///脚本单例类
	  ///</summary>
      public class MonoSingletonDontDestroy<T> : MonoBehaviour where T: MonoSingletonDontDestroy<T> 
  {
        //T 表示子类类型
        private static T instance;
        public static T Instance
        {
            get
            {
                if (instance==null)
                {
                    //在场景中根据类型查找引用
                    instance = FindObjectOfType<T>();

                    //如果忘记挂载 T这个脚本了 
                    if (instance==null)
                    {
                        //创建脚本对象(立即执行Awake)
                        new GameObject("Singleton of" + typeof(T).Name).AddComponent<T>();
                    }
                    else
                    {
                        //初始化
                        instance.Init();
                    }
                }
               
                return instance;
            }
        }
        /// <summary>
        /// 如果子类需要在Awake操作 重写这个方法
        /// </summary>
        public virtual void Init()
        {
            
        }

        protected void Awake()
        {
            Debug.Log("初始化");
            if (instance==null)
            {
                instance = this as T;
                Init();
            }
            else
            {
                if (instance!=this )
                {
                    Destroy(gameObject);
                }
            }
            DontDestroyOnLoad(gameObject);
        }

    }
}


一种是不继承Monobehaviour的类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
namespace Common
{
    public class Singleton<T> where T : new()
    {
        private static T instance;
        public static T Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new T();
                }
                return instance;
            }
        }


    }

}

使用方法都是一样的

 
打赏
 本文转载自:网络 
所有权利归属于原作者,如文章来源标示错误或侵犯了您的权利请联系微信13520258486
更多>最近资讯中心
更多>最新资讯中心
0相关评论

推荐图文
推荐资讯中心
点击排行
最新信息
新手指南
采购商服务
供应商服务
交易安全
关注我们
手机网站:
新浪微博:
微信关注:

13520258486

周一至周五 9:00-18:00
(其他时间联系在线客服)

24小时在线客服