Unity3D单例模式剖析

Unity作为一个脚本语言,我们可以很方便的直接把脚本挂在object上运行。这样的做法对于一些小游戏来说是非常的方便的,不用我们自己再用代码去主动的实例化对象,Unity自动帮我们实例化好了。但如果是对于大型项目来说就很麻烦了,因为大型项目每个模块都会有一定的关联性,也会有一定的解耦,过度的把脚本挂在Object上会使得脚本非常的难统一去管理。
在unity游戏项目中,为了更好的管理我们的游戏脚本,我们需要一个单例模式类作为游戏的初始启动点。通过APP Singleton类初始化游戏的配置参数,下载资源,加载场景等。话不多说,单例类贴上
using UnityEngine;
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace Joey
{

    /// <summary>
    /// 单线程下的简单单例模式
    /// </summary>
    public class SimpleSingleton
    {
        private static SimpleSingleton instance;

        public static SimpleSingleton Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new SimpleSingleton();
                }
                return instance;
            }
        }
        public SimpleSingleton(){ }
    }


    /// <summary>
    /// 多线程下的单例模式
    /// </summary>
    public class ThreadSingleton
    {

        private static ThreadSingleton instance;

        //定义一个标识确保线程同步
        private static readonly object locker=new object();

        //构造函数为Private防止外部实例化
        private ThreadSingleton()
        {

        }

        //当第一个线程运行过来会对locker添加锁
        //这里先判断instance是否为null,防止线程加锁后再去判断的话会进行额外的开销
        //当第二个线程过来的时候,会检测加锁状态,该线程就会挂起等待第一个线程解锁
        //lock语句完成后会对线程解锁
        public static ThreadSingleton GetInstance() 
        {

            if (instance==null) 
            {
                lock(locker)
                {
                    if (instance==null) 
                    {
                        instance=new ThreadSingleton();
                    }
                }
            }

            return instance;
        }
    }

    /// <summary>
    /// 继承于MonoBehavior下的单例模式
    /// 运用到泛型,是因为如果我们不用泛型的话,那么我们游戏中的每个单例脚本都要这样去写,这就很麻烦了。有了泛型之后就可以直接运用
    /// 看下面的实例类
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public class SingletonMono<T>:MonoBehaviour where T:Component
    {
        private static T instance;

        public static T Instace
        {
            get
            {
                if(instance==null)
                {
                    instance = FindObjectOfType(typeof(T)) as T;
                    if(instance==null)
                    {
                        GameObject obj = new GameObject();
                        obj.hideFlags = HideFlags.HideAndDontSave;
                        instance=obj.AddComponent<T>();
                    }
                }

                return instance;
            }
        }

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

    }

    public class SingletonTest:SingletonMono<SingletonTest>
    {

        public SingletonTest()
        {

        }
        public void Log()
        {
            Debug.Log("SingletonMono Test");
        }

    }


    public class Test
    {
        public Test()
        {
            SingletonTest.Instace.Log();
             //Manger.Instance
        }
    }

}

在Unity项目中经常用到的是带继承MonoBehavior的单例,但可能有时候我们并需要继承MonoBehavior类的管理类又该如何去使用单例呢。这个有位大神给我们了很好的代码。

大神链接:http://liangxiegame.com/unity-you-xi-kuang-jia-da-jian-er-dan-li-de-mo-ban/

主要代码:

using System;  
using System.Collections.Generic;  
using System.Text;  
using System.Reflection;

/// <summary>
/// 1.泛型
/// 2.反射
/// 3.抽象类
/// 4.命名空间
/// </summary>
namespace QFramework {  
    public abstract class QSingleton<T> where T : QSingleton<T>
    {
        protected static T instance = null;

        protected QSingleton()
        {
        }

        public static T Instance()
        {
            if (instance == null)
            {
                // 先获取所有非public的构造方法
                ConstructorInfo[] ctors = typeof(T).GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic);
                // 从ctors中获取无参的构造方法
                ConstructorInfo ctor = Array.Find(ctors, c => c.GetParameters().Length == 0);
                if (ctor == null)
                    throw new Exception("Non-public ctor() not found!");
                // 调用构造方法
                instance = ctor.Invoke(null) as T;
            }

            return instance;
        }
    }
}


// 1.需要继承QSingleton。
// 2.需要实现非public的构造方法。
public class XXXManager : QSingleton<XXXManager> {  
    private XXXManager() {
        // to do ...
    }
}


public static void main(string[] args)  
{
    XXXManager.Instance().xxxyyyzzz();
}

还有对于这些单例类 我们又该如何去管理呢,在此贴上另一个大神的链接

链接:http://blog.csdn.net/ycl295644/article/details/49487361

对于单例模式Unity3D官方也有示例代码:http://wiki.unity3d.com/index.php/Singleton

相信这些只是应该能够帮助大家对于Unity3D单例模式的用法有个足够的了解

发布了6 篇原创文章 · 获赞 3 · 访问量 6666

猜你喜欢

转载自blog.csdn.net/JoeyHuangzx/article/details/78350881
今日推荐