發表日(rì)期:5/20/2018 12:41:58 AM 浏覽次數:6092
最近(jìn)在做一個(gè)小(xiǎo)示例,發現(xiàn)類繼承于MonoBehaviour的(de)類,有(yǒu)很(hěn)多個(gè)方法,于是乎必然要問(wèn)出一個(gè)問(wèn)題:這(zhè)麽多個(gè)方法,執行先後順序是如何的(de)呢(ne)?內(nèi)部是如何進行管理(lǐ)的(de)呢(ne)?于是在網上(shàng)找了許多資料,發現(xiàn)了Richard Fine在2012年(nián)就已經發布了一篇文(wén)章(zhāng),而且講得算(suàn)是相(xiàng)當深入,并且很(hěn)有(yǒu)道(dào)理(lǐ)的(de),這(zhè)裏加上(shàng)我的(de)一些嘗試與思考,分享給大家(jiā)。
先貼上(shàng)圖,大家(jiā)有(yǒu)個(gè)直觀認識:
接下(xià)來(lái),做出一下(xià)講解:最先執行的(de)方法是Awake,這(zhè)是生(shēng)命周期的(de)開(kāi)始,用于進行激活時(shí)的(de)初始化(huà)代碼,一般可以在這(zhè)個(gè)地(dì)方将當前腳本禁用:this.enable=false,如果這(zhè)樣做了,則會直接跳(tiào)轉到OnDisable方法執行一次,然後其它的(de)任何方法,都(dōu)将不再被執行。
如果當前腳本處于可用狀态,則正常的(de)執行順序是繼續向下(xià)執行OnEnable,當然我們可以在另外(wài)一個(gè)腳本中實現(xiàn)這(zhè)個(gè)腳本組件(jiàn)的(de)啓動:this.enab=true;
再向下(xià)執行,會進行一個(gè)判斷,如果Start方法還(hái)沒有(yǒu)被執行,則會被執行一次,如果已經被執行了,則不會再被執行。這(zhè)是個(gè)什麽意思呢(ne)?我們可以在某個(gè)腳本中将組件(jiàn)禁用this.enable=false,再啓用時(shí)會轉到OnEnable處執行,這(zhè)時(shí)繼續向下(xià)走,發現(xiàn)Start執行過了,将不再被執行。比如說(shuō):第一次啓用時(shí),将怪物(wù)的(de)初始位置定在了(0,0,0)點,然後怪物(wù)可能會發生(shēng)了位置的(de)變換,後來(lái)被禁用了,再次啓用時(shí),不會讓怪物(wù)又(yòu)回到初始的(de)(0,0,0)位置。
繼續向後執行,就是Update了,然後是FixUpdate,再然後是LateUpdate,如果後面寫了Reset,則會又(yòu)回到Update,在這(zhè)4個(gè)事(shì)件(jiàn)間(jiān)可以進行循環流動。
再向後執行,就進入了渲染模塊(Rendering),非常重要的(de)一個(gè)方法就是OnGUI,用于繪制圖形界面。當然,如果你(nǐ)使用了NGUI,這(zhè)個(gè)生(shēng)命周期的(de)事(shì)情你(nǐ)就不用考慮了。
再向後,就是卸載模塊(TearDown),這(zhè)裏主要有(yǒu)兩個(gè)方法OnDisable與OnDestroy。當被禁用(enable=false)時(shí),會執行OnDisable方法,但(dàn)是這(zhè)個(gè)時(shí)候,腳本并不會被銷毀,在這(zhè)個(gè)狀态下(xià),可以重新回到OnEnable狀态(enable=true)。當手動銷毀或附屬的(de)遊戲對(duì)象被銷毀時(shí),OnDestroy才會被執行,當前腳本的(de)生(shēng)命周期結束。
特别要強調的(de)是:這(zhè)裏雖然可以使用C#來(lái)寫代碼,但(dàn)是這(zhè)個(gè)類構造對(duì)象的(de)生(shēng)命周期,與MonoBehaviour的(de)生(shēng)命周期,是完全不同的(de)。
可以通(tōng)過如下(xià)示例:對(duì)腳本進行驗證(兩個(gè)腳本添加到同一個(gè)遊戲對(duì)象上(shàng)):
腳本1Monster1:
void OnBecameInvisible()
{
Debug.Log("invisible");
MonsterController mc1 = this.gameObject.GetComponent<MonsterController>();
mc1.enabled = false;
}
void OnBecameVisible()
{
Debug.Log("visible");
MonsterController mc1 = this.gameObject.GetComponent<MonsterController>();
mc1.enabled = true;
}
腳本2MonsterController:
void Awake()
{
Debug.Log("awake");
this.enabled = false;
}
void OnEnable()
{
Debug.Log("enable");
this.enabled = true;
}
void Start()
{
Debug.Log("start");
//this.gameObject.SetActive(false);
}
void Update()
{
Debug.Log("update");
}
void OnGUI()
{
Debug.Log("gui");
}
void OnDisable()
{
Debug.Log("disable");
}
void OnDestroy()
{
Debug.Log("destroy");
}
如果您覺得有(yǒu)不對(duì)之處,歡迎指正,為(wèi)了技(jì)術進步,我們一起努力。