1. 程式人生 > >淺談Unity的指令碼執行順序

淺談Unity的指令碼執行順序

一、新增指令碼的順序

這是一張官方的指令碼順序圖

 

一般,當我們把指令碼繫結在遊戲物件上時,或者點選繫結好的指令碼的reset按鈕時,會呼叫Reset()

當我們初始化一個物件時,會先呼叫Awake()在呼叫OnEnable()

GameObject.instantiate(o);

start()在第一次呼叫update()前呼叫,有時候start()會在Awake(),OnEnable()執行完後立刻執行,處於同一幀

onDisable()和onDestroy()的執行順序有點特別:

第一種情況:

  對於不同物件上的不同的指令碼,執行是沒有先後規律的,且必須成對執行(呼叫完了onDisable()必須再呼叫onDestroy())

  eg:

gameobject1:
    sc1.cs
    sc2.cs
gameobject2:
    sc3.cs
    sc4.cs
gameobject3:
    sc5.cs
    sc6.cs

gameobject1.sc1.onDisable()->gameobject1.sc1.onDestroy()->gameobject3.sc5.onDisable()->

gameobject3.sc5.onDestroy()

[如果按前面的規則的話,應該先執行gameobject3的指令碼,但這裡不是]

第二種情況:

在同一個物件的不同的指令碼上,這兩個方法按照指令碼

在m_component中的索引按順序執行的,而且不是成對執行,索引自小到大執行,最早加入的最早呼叫onDisable()和onDestroy()

gemeobject2.sc3.onDisable()->gameobject2.sc4.onDisable()->

gameobject2.sc3.onDestroy->gameobject2.sc4.onDestroy()

這裡這些指令碼先依次呼叫onDisable()才呼叫onDestroy()。

二、如何自定義多個指令碼的執行順序

 

 劃重點:在unity裡面可以點選edit->project settings->Script->Execution Order中自定義指令碼執行順序,

當我們沒有設定指令碼執行順序時,指令碼按照Default Time的標準執行(你可以把unity裡面hireachy裡面新增物件和在inspector裡面新增指令碼

視作一個棧,按照先進先出原則,優先執行後新增的物件的先新增的Script。

可以單擊+號新增物件到執行列表中

1是指令碼的執行順序,當你的值execution order越小時,越先執行,在default time上方的在執行default time前執行,在default time下方

的在default time後執行

上面的設定,是通過修改每一個指令碼對應的meta檔案(去自己的程式碼目錄看一下)的excution order來實現的。

 

 三、指令碼執行順序的本質

在我們的場景檔案.unity,場景檔案是一個YAML文件

 

 每一個指令碼對應一個fileid,fileid越小越有先執行

 4.運用

如果你的指令碼A會用到另一個指令碼B中的某一個物件c,為了防止你在B初始化之前去呼叫c,出現空指標,你必須讓指令碼B在A之後掛載(這樣B就會先初始化),

還有一個很重要的地方,你必須把物件c的初始化寫在指令碼B的Awake()方法裡面,因為start()並不是在初始化就立刻呼叫的,而是在當前更新一幀時,start()

會在update()第一次呼叫前呼叫一次,這樣的話如果你把物件c的初始化寫在指令碼B的start()方法裡面,很有可能所有指令碼的awake()都跑完了,物件c卻沒有初始化,

這樣就出現了空指標。因此,把物件c的初始化在指令碼B的awake()方法,而把呼叫物件c寫在指令碼A的start()足夠