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();
}
}
寫在最后
#成功的道路沒有捷徑,代碼這條路更是如此,唯有敲才是王道。