Unity腳本週期概覽
運行Unity的腳本時,程序將會按照預定的順序去執行相應的函數,從腳本的初始化到腳本的銷燬,構成了腳本的生命週期。Unity腳本的生命週期預覽圖如下:
生命週期的不同階段
上圖中的多個函數可以根據其執行的時間段分爲以下不同階段。
首場景加載階段
以下的函數在場景加載時調用,且在加載時只調用一次(OnEnable可能在後續進行多次調用)
- Awake:在Prefab進行實例化後調用,位於Start函數前。(若GameObject在一開始就處於非激活狀態時,Awake則不會調用,直到該GameObject被激活)
- OnEnable:該函數在GameObject被激活時被調用。GameObject激活則是發生在一個MonoBehaviour實例被創建的時候。例如場景被加載或者一個擁有該腳本組件的GameObject被實例化時。注意: OnEnable首次調用是緊接Awake之後,對於同一腳本,若有多個物體創建時,是先執行完A物體的Awake->OnEnable函數,然後再執行B物體的Awake->OnEnable函數
- OnLevelWasLoaded:這個函數是用於通知有場景已經加載結束
編輯器階段
- Reset:當腳本被添加爲物體的組件時,Reset會被調用用於初始化腳本的屬性。或者當開發者執行Reset的編輯器操作時也會被調用。
第一幀更新前的階段
- Start:當腳本實例是可用狀態時,Start會在第一幀更新前調用
注:Start會在當前場景的所有物體執行Update前執行。
幀與幀之間的階段
- OnApplicationPause:該函數會在當前幀結束後下一幀開始前且檢測到暫停的時候回調
更新順序
當我們跟蹤遊戲的邏輯進行,如相機位置、人物動作的變化時我們會用到以下的更新函數,我們可以根據情況使用Update之外的函數來達到我們的目的
- FixedUpdate:FixedUpdate一般會比Update調用得更頻繁,當幀率較低時,他一幀內可能會調多次。所有的物理計算和Update函數都是在FixedUpdate函數之後。(是一個獨立於幀率外的回調函數)
- Update:一幀只會被調用一次。
- LateUpdate:一幀只會被調用一次,位於Update函數之後。該函數一般用於Update結束後的後續處理,例如 Update函數中來進行人物的移動,而LateUpdate則用於改變第三人稱相機的位置,這將能保證相機更新邏輯的準確。
渲染階段
- OnPreCull:相機剔除場景前被調用,屬於渲染流水線的一個環節。
- OnBecameVisible/OnBecameInvisible:當物體在任何相機中可見/不可見時調用。注意:Scene視圖的相機也需要考慮進去
- OnWillRenderObject:當物體在相機中可見時,他將爲各個相機調用一次
- OnPreRender:在相機開始渲染場景時調用
- OnRenderObject:在所有固定場景渲染完之後調用
- OnPostRender:在相機渲染完場景後調用
- OnRenderImage:場景渲染完使用,一般用於後期處理(如Glow)
- OnGUI:一幀會調用多次來響應GUI事件
- OnDrawGizmos :渲染Gizmos時調用
協程
普通的協程是在Update函數後進行更新的。
- yield:下一幀所有Update函數調用後,協程將會繼續執行
- yield WaitForSeconds:等待固定的秒數後協程繼續執行
- yield WaitForFixedUpdate:所有的FixedUpdate執行完後,協程繼續執行
- yield WWW:WWW下載完成後,協程繼續執行
- yield StartCoroutine XXFunc:鏈接協程,將會等XXFunc執行完後再繼續
對象銷燬階段
- OnDestroy:在對象存在的最後一幀調用,在所有的更新方法結束後調用
注意:調用Destroy(GO)時會先調用OnDisable,然後在所有的更新方法結束後調用OnDestroy
應用退出階段
在應用退出場景中的激活的對象會調用以下的函數:
- OnApplicationQuit:應用退出時所有的遊戲物體將會調用此函數(Editor中進行Stop操作也會)
- OnDisable:當物體被設置爲非激活狀態時調用