Unity MonoBehaviourイベントの実行順

# 概要
- MonoBehaviourの関数がどのような順番で実行されるか例を交えて説明します
- 少し特殊な事例についても紹介します

# ハマりポイント
- 非アクティブでGameObjectを生成した場合、アクティブになるまでMonoBehaviourのイベントは実行されない
    - 非アクティブのままオブジェクトを削除した場合`OnDestroy()`は呼ばれない
- ComponentがdisableでもGameObjectがアクティブであれば`Awake()`は呼ばれる

# 使用したソースコード
今回はこのコードをGameObjectにAddComponentしてイベントの実行順がどうなっているか調べていきます
ソースコードは長いので折りたたんでいます。

<details><summary>使用したコード</summary><div>

```C#
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");
    }
}


```

</div></details>

# GameObjectをアクティブ状態で生成して削除する
<img width="363" alt="スクリーンショット 2020-06-11 21.28.57.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105021/c221b084-1a46-4331-91db-621d9fdbd57a.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()`のループに戻ります。
<b>`Start()`は生成されてから1度しか呼ばれないので、アクティブ・非アクティブを切り替えても2回以上呼ばれることはありません。</b>

# GameObjectを非アクティブ状態で生成し、アクティブに切り替えてから削除する
<img width="134" alt="スクリーンショット 2020-06-11 21.38.21.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105021/bd5ca544-9721-cb98-4c32-34c3eb7a3261.png">
<img width="313" alt="スクリーンショット 2020-06-11 21.37.56.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105021/3f936a0c-770d-7c2a-cb75-28545b48c59f.png">

次にGameObjectを非アクティブで生成した場合のイベント実行順です。

```
~~~Unity実行開始
~~~GameObjectをアクティブに切り替え
Awake()
OnEnable()
Start()
Update()
LateUpdate()
Update()
LateUpdate()
...
~~~オブジェクトの削除実行
OnDisable()
OnDestroy()
```

<b>非アクティブな間は何も関数が呼ばれません。</b>
アクティブになって初めて`Awake()`→`OnEnable()`→`Start()`の順番でイベントが呼び出されます。

# GameObjectを非アクティブ状態で生成し、そのまま削除する

<b>このパターンが最も注意が必要です。
いっさい関数が呼び出されません。</b>

```
~~~Unity実行開始
~~~オブジェクトの削除実行
```

オブジェクトを削除したのに`OnDestroy()`が呼ばれないのでハマりやすいパターンになります。

# GameObjectを非アクティブ状態で生成し、アクティブ→非アクティブと切り替えてから削除する
上と似たようなパターンですが、挙動が異なります。

```
~~~Unity実行開始
~~~オブジェクトをアクティブに
Awake()
OnEnable()
Start()
Update()
LateUpdate()
Update()
LateUpdate()
...
~~~オブジェクトを非アクティブに戻す
OnDisable()
~~~オブジェクトの削除実行
OnDestroy()
```

この場合は`OnDisable()`や`OnDestroy()`も正しく呼び出されます。

# GameObjectはアクティブだが、Componentはdisableで生成し、その後enableに切り替える
<img width="322" alt="スクリーンショット 2020-06-11 22.08.14.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/105021/6f92cc4c-0815-8db5-70b9-9e5d1eef4cfd.png">

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

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

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

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

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


# Unity 公式資料
- [イベント関数の実行順序](https://docs.unity3d.com/ja/2018.4/Manual/ExecutionOrder.html)