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();
}
}
写在最后
#成功的道路没有捷径,代码这条路更是如此,唯有敲才是王道。