Unity技术博客 - 单例的使用

作者: 肖马克_蛮牛 | 来源:发表于2015-10-20 19:53 被阅读4129次

    Unity版本: 4.6

    使用语言: C#


    写在前面

      单例是项目开发过程中经常使用到的一中设计模式,个人认为单例也是最简单的一种设计模式。
      单例的作用其实很简单,只要记住单例单例,保证一个实例就👌了。
      单例的优点:保证一个实例,方便其他脚本调用。
    

    实现功能:

       1.保证类只有一个实例
       2.提供只读属性,方便其他脚本调用
       3.实现切换场景之后对象不销毁(第四种写法有介绍)
    

    这里为大家介绍Unity中常见的四种单例写法:

    • 1 不继承自MonoBehaviour的脚本


    public class BagManager {

    //第一步构造方法私有化,保证外部不能实例化
    private BagManager(){}  
    //第二步定义静态私有成员(注意类型跟类名相同)
    private static BagManager instance;
    //第三步封装只读属性,提供对外访问私有成员的接口
    public static BagManager Instance {
        get {
            if(instance == null)
            {
                instance = new BagManager();
            }
            return instance;
        }
    }
    

    }


    注意:这种单例写法没有考虑多线程(菜鸟的略过)。

    • 2 继承自MonoBehaviour的脚本


    public class Singleton : MonoBehaviour {

    //定义静态成员(静态的可以通过类名访问)
    //所有的单例都需这一步,提供对外访问的接口
    public static Singleton Instance{get; private set;}
    void Awake()
    {
        //this表示当前对象
        Instance = this; 
    }
    

    }

    注意:这种单例写法需要将脚本手动赋给一个GameObject(缺陷)。

    • 3 继承自MonoBehaviour的脚本


    public class Singleton : MonoBehaviour {

    //定义静态成员(静态的可以通过类名访问)
    private static Singleton instance;
    //封装属性
    public static Singleton Instance{
        get
        {
            if(instance == null)
            {
                //用代码生成一个GameObject
                GameObject obj = new GameObject();
                obj.name = "Singleton";
                //给生成的物体添加脚本(将这个方法的返回值赋给instance)
                instance = obj.AddComponent<Singleton>();
            }
            return instance;
        }
    }
    

    }

    注意:继承自MnoBehaviour的类不允许写私有的构造方法。该脚本无须挂到游戏物体上,其他脚本可以直接使用。

    • 4 继承自单例模板类

      优点:使用框架写法无非就是省代码。如果有多个单例类,省去了相同代码部分。
      

    //<i>使用泛型,需要加限制(泛型类型必须是继承自MonoBehaviour的脚本)</i>
    public class Singleton<T> : MonoBehaviour where T : MonoBehaviour
    {
    private static T instance;

    public static T Instance {
        get {
            if(instance == null)
            {
                GameObject obj = new GameObject();
                instance = obj.AddComponent<T>();
                obj.name = typeof(T).Name;
                //切换场景之后不销毁单例对象
                DontDestroyOnLoad(obj);
            }
            return instance;
        }
    }
    

    }

    using UnityEngine;
    using System.Collections;

    [RequireComponent(typeof(AudioSource))]

    public class MusicManager : Singleton<MusicManager> {

    private AudioClip bgMusic;
    private AudioSource audio;
    
    void Init()
    {
        bgMusic = Resources.Load("Music/bgMusic") as AudioClip;
        audio = GetComponent<AudioSource>();
        if(!audio)
        {
            audio = this.gameObject.AddComponent<AudioSource>();
        }
        audio.clip = bgMusic;
    }
    
    public void Play()
    {
        if(bgMusic == null || !audio)
        {
            Init();
        }
        audio.Play();
    }
    
    public void Stop()
    {
        if(bgMusic == null || !audio)
        {
            Init();
        }
        audio.Stop();
    }
    

    }


    写在最后

     #成功的道路没有捷径,代码这条路更是如此,唯有敲才是王道。

    相关文章

      网友评论

      本文标题:Unity技术博客 - 单例的使用

      本文链接:https://www.haomeiwen.com/subject/gaazcttx.html