Unity版本: 4.6
使用語(yǔ)言: C#
寫(xiě)在前面
單例是項(xiàng)目開(kāi)發(fā)過(guò)程中經(jīng)常使用到的一中設(shè)計(jì)模式尊浪,個(gè)人認(rèn)為單例也是最簡(jiǎn)單的一種設(shè)計(jì)模式酥诽。
單例的作用其實(shí)很簡(jiǎn)單状囱,只要記住單例單例尽超,保證一個(gè)實(shí)例就??了。
單例的優(yōu)點(diǎn):保證一個(gè)實(shí)例宏蛉,方便其他腳本調(diào)用祠肥。
實(shí)現(xiàn)功能:
1.保證類(lèi)只有一個(gè)實(shí)例
2.提供只讀屬性,方便其他腳本調(diào)用
3.實(shí)現(xiàn)切換場(chǎng)景之后對(duì)象不銷(xiāo)毀(第四種寫(xiě)法有介紹)
這里為大家介紹Unity中常見(jiàn)的四種單例寫(xiě)法:
-
1 不繼承自MonoBehaviour的腳本
public class BagManager {
//第一步構(gòu)造方法私有化,保證外部不能實(shí)例化
private BagManager(){}
//第二步定義靜態(tài)私有成員(注意類(lèi)型跟類(lèi)名相同)
private static BagManager instance;
//第三步封裝只讀屬性被去,提供對(duì)外訪問(wèn)私有成員的接口
public static BagManager Instance {
get {
if(instance == null)
{
instance = new BagManager();
}
return instance;
}
}
}
注意:這種單例寫(xiě)法沒(méi)有考慮多線程(菜鳥(niǎo)的略過(guò))主儡。
-
2 繼承自MonoBehaviour的腳本
public class Singleton : MonoBehaviour {
//定義靜態(tài)成員(靜態(tài)的可以通過(guò)類(lèi)名訪問(wèn))
//所有的單例都需這一步,提供對(duì)外訪問(wèn)的接口
public static Singleton Instance{get; private set;}
void Awake()
{
//this表示當(dāng)前對(duì)象
Instance = this;
}
}
注意:這種單例寫(xiě)法需要將腳本手動(dòng)賦給一個(gè)GameObject(缺陷)惨缆。
-
3 繼承自MonoBehaviour的腳本
public class Singleton : MonoBehaviour {
//定義靜態(tài)成員(靜態(tài)的可以通過(guò)類(lèi)名訪問(wèn))
private static Singleton instance;
//封裝屬性
public static Singleton Instance{
get
{
if(instance == null)
{
//用代碼生成一個(gè)GameObject
GameObject obj = new GameObject();
obj.name = "Singleton";
//給生成的物體添加腳本(將這個(gè)方法的返回值賦給instance)
instance = obj.AddComponent<Singleton>();
}
return instance;
}
}
}
注意:繼承自MnoBehaviour的類(lèi)不允許寫(xiě)私有的構(gòu)造方法糜值。該腳本無(wú)須掛到游戲物體上丰捷,其他腳本可以直接使用。
-
4 繼承自單例模板類(lèi)
優(yōu)點(diǎn):使用框架寫(xiě)法無(wú)非就是省代碼寂汇。如果有多個(gè)單例類(lèi)病往,省去了相同代碼部分。
//<i>使用泛型骄瓣,需要加限制(泛型類(lè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;
//切換場(chǎng)景之后不銷(xiāo)毀單例對(duì)象
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();
}
}
寫(xiě)在最后
#成功的道路沒(méi)有捷徑停巷,代碼這條路更是如此,唯有敲才是王道榕栏。