概要
- MonoBehaviourの関数がどのような順番で実行されるか例を交えて説明します
- 少し特殊な事例についても紹介します
ハマりポイント
- 非アクティブでGameObjectを生成した場合、アクティブになるまでMonoBehaviourのイベントは実行されない
- 非アクティブのままオブジェクトを削除した場合
OnDestroy()
は呼ばれない
- 非アクティブのままオブジェクトを削除した場合
- ComponentがdisableでもGameObjectがアクティブであれば
Awake()
は呼ばれる
使用したソースコード
今回はこのコードをGameObjectにAddComponentしてイベントの実行順がどうなっているか調べていきます
ソースコードは長いので折りたたんでいます。
使用したコード
using UnityEngine;
public class LifeCycle : MonoBehaviour
{
private void Awake()
{
Debug.Log("Awake");
}
private void OnEnable()
{
Debug.Log("OnEnable");
}
private void Start()
{
Debug.Log("Start");
}
private void Update()
{
Debug.Log("Update");
}
private void LateUpdate()
{
Debug.Log("LateUpdate");
}
private void OnDisable()
{
Debug.Log("OnDisable");
}
private void OnDestroy()
{
Debug.Log("OnDestroy");
}
}
GameObjectをアクティブ状態で生成して削除する
最も使うパターンだと思います。
この場合イベント実行順は以下のようになります
~~~Unity実行開始
Awake()
OnEnable()
Start()
Update()
LateUpdate()
Update()
LateUpdate()
...
~~~オブジェクトの削除実行
OnDisable()
OnDestroy()
オブジェクトが生成された段階で
Awake()
→OnEnable()
→Start()
の順番で呼ばれ
そのあとは基本ループの
Update()
→LateUpdate()
が呼ばれます。
削除が実行されたあとは
OnDisable()
→OnDestroy()
の順番でイベントが呼ばれます。
GameObjectをアクティブ状態で生成し、非アクティブ→アクティブと切り替える
これもよく使うパターンです。
イベント実行順は以下のようになります
~~~Unity実行開始
Awake()
OnEnable()
Start()
Update()
LateUpdate()
Update()
LateUpdate()
...
~~~オブジェクトを非アクティブに
OnDisable()
~~~オブジェクトをアクティブに戻す
OnEnable()
Update()
LateUpdate()
Update()
LateUpdate()
...
非アクティブにした際にOnDisable()
が呼び出され、Update()
とLateUpdate()
の呼び出しが止まります。
再びアクティブに戻した時はOnEnable()
が呼び出され、Update()
とLateUpdate()
のループに戻ります。
Start()
は生成されてから1度しか呼ばれないので、アクティブ・非アクティブを切り替えても2回以上呼ばれることはありません。
GameObjectを非アクティブ状態で生成し、アクティブに切り替えてから削除する
次にGameObjectを非アクティブで生成した場合のイベント実行順です。
~~~Unity実行開始
~~~GameObjectをアクティブに切り替え
Awake()
OnEnable()
Start()
Update()
LateUpdate()
Update()
LateUpdate()
...
~~~オブジェクトの削除実行
OnDisable()
OnDestroy()
非アクティブな間は何も関数が呼ばれません。
アクティブになって初めてAwake()
→OnEnable()
→Start()
の順番でイベントが呼び出されます。
GameObjectを非アクティブ状態で生成し、そのまま削除する
このパターンが最も注意が必要です。
いっさい関数が呼び出されません。
~~~Unity実行開始
~~~オブジェクトの削除実行
オブジェクトを削除したのにOnDestroy()
が呼ばれないのでハマりやすいパターンになります。
GameObjectを非アクティブ状態で生成し、アクティブ→非アクティブと切り替えてから削除する
上と似たようなパターンですが、挙動が異なります。
~~~Unity実行開始
~~~オブジェクトをアクティブに
Awake()
OnEnable()
Start()
Update()
LateUpdate()
Update()
LateUpdate()
...
~~~オブジェクトを非アクティブに戻す
OnDisable()
~~~オブジェクトの削除実行
OnDestroy()
この場合はOnDisable()
やOnDestroy()
も正しく呼び出されます。
GameObjectはアクティブだが、Componentはdisableで生成し、その後enableに切り替える
特殊なパターンです。
このパターンの場合、Objectを生成した時はAwake()
だけが呼ばれます。
~~~Unity実行開始
Awake()
~~~Componentをenableに
OnEnable()
Start()
Update()
LateUpdate()
Update()
LateUpdate()
...
GameObjectはアクティブだが、Componentはdisableで生成し、その後削除する
特殊なパターンその2です
この時はOnDestroy()
が呼ばれます。
以上の例から、1度でもAwake()
が呼び出されるシチュエーションを経由していないとOnDestroy()
は呼ばれないということがわかります。
~~~Unity実行開始
Awake()
~~~オブジェクトの削除実行
OnDestroy()