Unity MonoBehavior

MonoBehaviour 是 Unity 中最重要的基類之一,用於控制遊戲物件(GameObject)的行為。並提供了一系列生命週期方法,這些方法在遊戲物件生命週期的不同階段會被調用。此外,還提供了一些輔助方法,用於執行常見任務,例如訪問遊戲物件和組件(Component)。


生命週期方法 (Lifecycle methods)

MonoBehaviour 提供了一系列生命週期方法,這些方法在遊戲物件生命週期的不同階段會被調用。這些方法包括

  • Awake:此方法在遊戲物件(GameObject)實體被建立時呼叫一次。
    • 通常用來:在APP開始前初始化遊戲物件狀態屬性,例如設置變量、添加組件(Component)等。
    • Unity會在所有啟用的遊戲物件都實體化之後,才呼叫Awake,所以可以呼叫FindWithTag,而不用擔心找不到啟用的遊戲物件。
    • Awake不可以使用協程(Awake cannot act as a coroutine)
    • 注意:Unity 不會保證用特定的順序調用每個遊戲物件的 Awake 方法。因此,不可以假設一個遊戲物件的 Awake 方法會在另一個遊戲物件的 Awake方法之前或之後調用。
      • 正確的方式是在 Awake 中設置自身的屬性和取得其他物件的引用,而在 Start 方法中處理需要依賴其他遊戲物件的屬性和引用。
    • 注意:如果如果遊戲物件是啟用(Enable)但是腳本(Script)並沒有被啟用,Awake依然會被執行。
      • 如果如果遊戲物件是啟用但是腳本並沒有被啟用,Awake依然會被執行
  • OnEnable:啟用時才會呼叫,在Awake之後執行,每次啟用都會呼叫
    • 通常在此註冊事件
  • Start:此方法在遊戲物件的所有組件都已初始化且第一幀渲染之前調用一次。
    • 當這個遊戲物件處於 Disabled 就不會呼叫,直到該物件第一次被啟用時,才呼叫。
    • 通常用來:處理開始遊戲物件開始的遊戲邏輯。
    • 是在AwakeOnEnable之後呼叫
    • Start可以使用協程 (Coroutine)
  • Update:此方法在遊戲的每一幀調用。
    • 當物件為啟用時才會呼叫Update
    • 通常用來:更新遊戲物件的狀態和處理使用者輸入。
  • FixedUpdate:此方法在固定的時間間隔調用,通常每 0.02 秒調用一次。
    • 通常用來:在此方法更新遊戲物件的物理模擬
    • 設定FixedUpdate的時間間隔
  • LateUpdate:此方法在所有的 Update 方法之後調用。
    • 它是更新依賴於 Update 方法結果的遊戲邏輯的理想場所。
    • 例如:攝影機跟隨(follow camera)就很適合放在此,因為它需要跟隨那些可能在 Update 中已經移動過的物件。
  • OnDisable:與OnEnable類似,但是是非啟用時才會呼叫,每次非啟用都會呼叫
    • 通常在此取消註冊事件
    • 當遊戲物件為disable時,不會呼叫UpdateFixedUpdateLateUpdate等相關更新方法。
    • 當遊戲物件為disable時,物件仍然在場景(Scene)中,該物件仍不會被釋放。
  • OnDestroy:此方法在遊戲物件被銷毀時調用一次。物件從場景(Scene)中被移除了,該物件所佔用的記憶體可以被釋放。
    • 當原先場景關閉,載入新的場景時,也會觸發OnDestroy方法
    • 通常用來:清理遊戲物件使用的資源。
    • 如果如果遊戲物件是啟用(Enable)但是腳本(Script)並沒有被啟用,移除該物件時,OnDestroy依然會被執行。
    • 注意:如果使用者是在手機平台上,那麼當使用者暫停你的APP時,作業系統(OS)可能會終止你的APP,而不會觸發 OnDestroy 方法,因此不要依賴此方法來保存APP的狀態。請將每次應用程序失去焦點視為APP退出,並使用 MonoBehaviour.OnApplicationFocus 來保存資料。

注意:
在Unity中預設是不會控制Script的執行順序,Unity的執行會先將所有腳本的Awake執行完之後,才去執行所有腳本的Start,如果真的需要依賴順序你需要到ProjectSetting中的Script Exceution Order去設定順序,數字越小的越先執行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class A : MonoBehaviour
{
// 最先呼叫
private void Awake()
{
Debug.Log($"{nameof(A)} is Awake");
}

// 啟用時才會呼叫,在Awake之後執行,每次啟用都會呼叫
private void OnEnable()
{
Debug.Log($"{nameof(A)} is OnEnable");
}

// 在第一幀開始前執行
void Start()
{
Debug.Log($"{nameof(A)} is Start");
}

// 每一幀執行
void Update()
{
Debug.Log($"{nameof(A)} is Update");
}

// 在 Update 之後執行,也是每一幀執行
private void LateUpdate()
{
Debug.Log($"{nameof(A)} is LateUpdate");
}

// 固定時間呼叫
private void FixedUpdate()
{
Debug.Log($"{nameof(A)} is FixedUpdate");
}

// 非啟用時才會呼叫,每次非啟用都會呼叫
private void OnDisable()
{
Debug.Log($"{nameof(A)} is OnDisable");
}

// 目前Component銷毀時才會呼叫
private void OnDestroy()
{
Debug.Log($"{nameof(A)} is OnDestroy");
}
}

Reference:

評論