一、添加腳本的順序
這是一張官方的腳本順序圖
一般,當我們把腳本綁定在游戲對象上時,或者點擊綁定好的腳本的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()足夠安全