單例模式(上)和 工廠模式
大家好鳞仙,我是北京菜鳥在線的范老師,主講 unity3d 笔时。講師棍好。今天給大家講的是單例模式和工廠模式
一:新創(chuàng)建一個(gè)場(chǎng)景,創(chuàng)建一個(gè)國王Cube, N個(gè)Sphere士兵允耿。并給國王賦給標(biāo)簽 tag== King.
1-1 這個(gè)國王Cube上掛的代碼如下:
using UnityEngine;
using System.Collections;
//國王腳本
public class King : MonoBehaviour {
// 國王名字
public string mName;
// 國王的血量
public int mHP = 100;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Input .GetKeyDown(KeyCode.A))
{ //如果每次按下按鍵A借笙,國王的血量就減去10
mHP -= 10;
print(mHP);
if (mHP < 50)
{
Application.LoadLevel("DanLiMOshi001" );
}
}
}
}
1-2 :上面是掛到國王的上的腳本,那么掛在士兵上的腳本如下:
using UnityEngine;
using System.Collections;
// 士兵的腳本
public class Soldier : MonoBehaviour {
//士兵的名字
public string mName;
public King mKingName; //國王名字
//查找國王有幾種方法:第一種较锡,public 公開业稼,然后拖上去,效率最高
void Start () {
// 第二種查找國王的方法;Find,這適合于只有一個(gè)的名字蚂蕴,字符串匹配低散,效率最底
// mKingName = GameObject.Find("Cube").GetComponent<King>();
//第三種:通過標(biāo)簽查找,第一個(gè)字符串King是添加的標(biāo)簽俯邓。第二個(gè)king 是這類標(biāo)簽上的一個(gè)腳本king
mKingName = GameObject.FindGameObjectWithTag("King" ).GetComponent<King>();
CompeteMission();
}
private void CompeteMission()
{ //每個(gè)士兵都可以完成任務(wù)
print(mKingName.name + "我" + mName + "完成任務(wù)了!" );
}
}
1-3 : 新建一個(gè)場(chǎng)景熔号,當(dāng)國王的血量少于50的時(shí)候稽鞭,可以跳轉(zhuǎn)場(chǎng)景。具體代碼如上面引镊。跳轉(zhuǎn)另一個(gè)場(chǎng)景之后朦蕴,隔5.0秒之后,自動(dòng)再跳轉(zhuǎn)過來這個(gè)場(chǎng)景弟头。
另一個(gè)場(chǎng)景像機(jī)上掛的代碼如下:
using UnityEngine;
using System.Collections;
// 跳轉(zhuǎn)場(chǎng)景后吩抓,5.0秒后,自動(dòng)跳轉(zhuǎn)到另一個(gè)場(chǎng)景赴恨。
public class test : MonoBehaviour {
// Use this for initialization
void Start () {
Invoke( "Return",5.0f);
}
void Return()
{
Application.LoadLevel("DanLiMOshi" );
}
}
需要注意的是:
Invoke() 方法是 Unity3D 的一種委托機(jī)制
如: Invoke("SendMsg", 5); 它的意思是:5 秒之后調(diào)用 SendMsg() 方法琴拧;
使用
Invoke() 方法需要注意 3點(diǎn):
1 :它應(yīng)該在 腳本的生命周期里的(Start、Update嘱支、OnGUI蚓胸、FixedUpdate、LateUpdate)中被調(diào)用除师;
2:Invoke(); 不能接受含有 參數(shù)的方法沛膳;
3:在 Time.ScaleTime = 0; 時(shí), Invoke() 無效汛聚,因?yàn)樗粫?huì)被調(diào)用到
Invoke() 也支持重復(fù)調(diào)用:InvokeRepeating("SendMsg", 2 , 3);
這個(gè)方法的意思是指:2 秒后調(diào)用 SendMsg() 方法锹安,并且之后每隔 3 秒調(diào)用一次 SendMsg () 方法
1-4 :當(dāng)場(chǎng)景跳轉(zhuǎn)過來以后,我們發(fā)現(xiàn)倚舀,上次是當(dāng)國王的血量少于等于50的時(shí)候叹哭,才時(shí)行的跳轉(zhuǎn),可是痕貌,跳轉(zhuǎn)過來后风罩,發(fā)現(xiàn),國王的血量舵稠,又是滿血了超升。那么,如果哺徊,我們想保持原來國王的血量室琢,我們要怎么做呢,當(dāng)我們?cè)趪醯拇a里添加上:
void Awake()
{ // 加載時(shí)不銷毀
DontDestroyOnLoad( this.gameObject);
}
我們發(fā)現(xiàn)落追,跳轉(zhuǎn)場(chǎng)景后盈滴,生成了兩個(gè)國王,一個(gè)是100的血量轿钠,一個(gè)是保持了原來小于50的血量巢钓。但是病苗,如果來回的切換場(chǎng)景,那么一次多生成一個(gè)竿报,玩的次數(shù)越多铅乡,場(chǎng)景中的國王就會(huì)越多。
那么烈菌,問題又來了阵幸,我們希望保持原來的數(shù)據(jù),又不希望生成 新的國王的數(shù)據(jù)芽世,怎么辦呢
我們可以考慮在第一個(gè)場(chǎng)景中挚赊,開始的時(shí)候,在國王的身上济瓢,我們不給它掛腳本荠割,只是在像機(jī)上掛 個(gè)腳本,讓國王跳轉(zhuǎn)場(chǎng)景的時(shí)候旺矾,實(shí)例化出來蔑鹦。預(yù)制體如下圖
像機(jī)上掛腳本,把做好的國王的預(yù)制體拉到像機(jī)上的腳本上箕宙。士兵的上的腳本就可以不要了嚎朽。如下圖,
1-5 運(yùn)行程序后柬帕,發(fā)現(xiàn)哟忍。在我們的第一個(gè)場(chǎng)景中,一直有實(shí)例化的國王陷寝,那么锅很,我們就要進(jìn)行判斷。發(fā)現(xiàn)都正常了凤跑,一直都是一個(gè)了爆安。如下圖:
代碼如下:
using UnityEngine;
using System.Collections;
// 一開始,實(shí)例化出來一個(gè)國王
public class CreatePlayer : MonoBehaviour {
public King mKing;
// 因?yàn)殪o態(tài)變量在該類里面有且只有一個(gè)實(shí)例饶火,所以鹏控,我們可以用它來長期儲(chǔ)存該實(shí)例,那么這個(gè)變量的生命周期可以持續(xù)到游戲開始到結(jié)束肤寝。
//我們也可以把把它聲明成public ,方便其它類的對(duì)象的調(diào)用。
public static King sKing = null;
// 單例模式抖僵,只會(huì)在程序結(jié)束的時(shí)候鲤看,才會(huì)銷毀。這個(gè)靜態(tài)的可以寫在任何的腳本里耍群。寫在哪里都可以义桂。
// Use this for initialization
void Start () {
if (sKing == null )
{
sKing = ( King)Instantiate(mKing);
}
}
// Update is called once per frame
void Update () {
}
}
<待續(xù)>