LoginSignup
8
5

More than 3 years have passed since last update.

Unity MonoBehaviourイベントの実行順

Last updated at Posted at 2020-06-11

概要

  • 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をアクティブ状態で生成して削除する

スクリーンショット 2020-06-11 21.28.57.png

最も使うパターンだと思います。
この場合イベント実行順は以下のようになります

~~~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を非アクティブ状態で生成し、アクティブに切り替えてから削除する

スクリーンショット 2020-06-11 21.38.21.png
スクリーンショット 2020-06-11 21.37.56.png

次に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に切り替える

スクリーンショット 2020-06-11 22.08.14.png

特殊なパターンです。
このパターンの場合、Objectを生成した時はAwake()だけが呼ばれます。

~~~Unity実行開始
Awake()
~~~Componentをenableに
OnEnable()
Start()
Update()
LateUpdate()
Update()
LateUpdate()
...

GameObjectはアクティブだが、Componentはdisableで生成し、その後削除する

特殊なパターンその2です
この時はOnDestroy()が呼ばれます。
以上の例から、1度でもAwake()が呼び出されるシチュエーションを経由していないとOnDestroy()は呼ばれないということがわかります。

~~~Unity実行開始
Awake()
~~~オブジェクトの削除実行
OnDestroy()

Unity 公式資料

8
5
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
5