[Live] MonoBehaviour 機制說明與測試 – Testing MonoBehaviour Message

前幾天有場直播跟大家分享我對 Unity MonoBehaviour 的一些心得,花了一個小時左右跟觀眾討論一些在 Unity 開發時容易遇到的問題,以及一些零碎的小細節。

之後的一個多小時,則是閱讀 Unity 官方文件以及進行測試,目的是希望了解 Awake、Start、Update、OnDestroy、OnEnable 等 MonoBehaviour 事件(Message enent) 的執行細節。

直播紀錄與實驗紀錄如下:

2017/2/21 直播紀錄 (Unity 開發 | Monobehaviour 機制說明與測試)

直播及後續研究得到的一些結論

關於場景初始化

  • 對於一個物件,初始化動作的執行順序為 Awake > OnEnable > Start。
  • 進入場景後,所有物件的 Awake、OnEnable 都會在所有物件的 Start 之前執行;換句話說, Awake、OnEnable 是初始化的階段一,Start 是初始化的階段二。
    • 對開發腳本的建議是,Awake 不要使用到橫跨腳本或物件的功能,如 GameObject.Find 及 gameObject.GetComponent 後制執行方法或存取變數。
  • 數個物件之間並沒有保證 Awake 一定會在 OnEnable 之前。
  • 對於剛進入場景時便存在的物件而言,物件之間 Start 必定在 Update 之前,但後來被建立的物件則不再此限。
    • 建議不要依賴這項原則,可能會造成物件或腳本的不穩定。

關於 Instantiate

  • 在 GameObject.Instantiate 語法執行完的同時,可以理解為 Awake、OnEnable 都被執行過了,但 Start 並還沒執行。
  • Start 跟 Update 會在同一個 Frame 執行,但依據 GameObject.Instantiate 語法執行的時間點,可能會需要等到下一個 Frame。

關於 Destroy

  •  執行了 GameObject.Destroy 語法的當下,並不會執行 OnDestroy,所以有即時動作之必要時,不建議使用 OnDestroy。
  • OnDestroy 執行的時間點,是在該物件最後一次執行 Update 之後。

更多關於 Awake、Start、FixedUpdate

  • Awake 基本上一定會被執行到。
  • 如果物件還沒執行 Start 就遭到 Destory,則 Start 不會執行。
  • FixedUpdate 是物理邏輯所使用,雖然是固定的時間運作,但對於 Frame 更新來說,它是不同步的,使用 FixedUpdate 來處理畫面相關可能會造成畫面的不連續的延遲感。

關於切換場景

  • 因為 MonoBehaviour 的 Coroutine 多在 Update 階段執行,所以 Coroutine 中的動作不會早於新場景的 Awake、OnEnable、Start
  • Coroutine 是依附於 MonoBehaviour 及物件上,所以切換場景後,不論 Coroutine 中的工作是否完成,都會被銷毀。
    • 所以建議要在 Coroutine 中執行場景切換,或跨場景相關的工作,要採用 DontDestroy 物件或 Singleton pattern。

後話

這是一場臨時且雜亂的直播 (而且前半音效設備有狀況),不過在開頭的一個小時因為有觀眾互動,我就嘰嘰喳喳地說了很多零碎的感想,希望有帶給觀眾有用的資訊。

關於場景切換時,該如何插入一些腳本工作在初始化階段之中或之前,還沒有確定結論。如果有了新的結果會在分享給大家。

2017/02/28 update:

新文章補完了關於場景切換中,安插腳本的流程 (Flow) 測試

廣告

發表迴響

在下方填入你的資料或按右方圖示以社群網站登入:

WordPress.com Logo

您的留言將使用 WordPress.com 帳號。 登出 / 變更 )

Twitter picture

您的留言將使用 Twitter 帳號。 登出 / 變更 )

Facebook照片

您的留言將使用 Facebook 帳號。 登出 / 變更 )

Google+ photo

您的留言將使用 Google+ 帳號。 登出 / 變更 )

連結到 %s