［UE5］UEのC++、Blueprintの実行順番

# 概要
この記事では、C++のコンストラクタ、BeginPlay、EndPlayと、BlueprintのBeginPlay、EndPlayがどのような順番で呼ばれているのかを、アクタを用いて検証します。

また、アクタ、パーシスタントレベル、サブレベルのBlueprintおける、各関数の実行順番も検証します。

結果だけご覧になりたい方は、[こちら](#検証結果まとめ)をご覧ください。


# この記事の主な対象者
- Unreal Engine初心者の方

# 前提知識
Unreal Engineでは、C++にデストラクタはありません。
またBlueprintには、コンストラクタとデストラクタはありません。（ただし、UMGにはコンストラクタとデストラクタがあります。）

# アクタにおけるC++、Blueprintの実行順番

アクタにおけるC++、Bluepritnの実行順番を確認していくにあたって、最初に、筆者がC++で作成したクラスを親クラスに設定したアクタのBlueprintを作成しました。

![parentclass.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/5d14c05c-d725-cc3d-5317-f66b681b2825.jpeg)<br><br>

また、C++とBlueprintの各関数（C++のコンストラクタ、C++とBlueprintのBeginPlay、EndPlay）が呼び出されたときに、ゲームプレイ画面に下の形式でメッセージを表示するようにしました。

```
[C+ or BP] -> [関数名]
```
（C+ = C++、BP = Blueprint）
<br>

また、C++ の BeginPlay では Super::BeginPlay() の前と後にメッセージを表示する処理を書き、前だったら「C+ -> BeginPlay before Super」、後だったら「C+ -> BeginPlay after Super」と表示するようにしました。

EndPlayにおいても、同様のことを行いました。
<br>

アクタをスポーンした直後に、スポーンしたアクタをDestroyする処理を行うことで、各関数の実行順番を確認したところ、下図のように表示されていました。

![beginendorder3.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/556dcc24-1490-bc7a-0a3b-14bdb7627f21.jpeg)<br><br>


上図において、下に表示されている文字の方が早く実行されているので、C++とBlueprintの各関数（C++のコンストラクタ、C++とBlueprintのBeginPlay、EndPlay）の実行順番は、下記の順番であるということがわかりました。<br><br>

1. C++のコンストラクタ
1. C++のBeginPlay（Super::BeginPlay()の前）
1. BlueprintのBeginPlay
1. C++のBeginPlay（Super::BeginPlay()の後）
1. C++のEndPlay（Super::EndPlay()の前）
1. BlueprintのEndPlay
1. C++のEndPlay（Super::EndPlay()の後）
<br>

**C++ の Super::[関数名] を呼ぶ際に、Blueprint の関数が呼ばれている**ということがわかったので、C++とBlueprintのBeginPlayやEndPlayで同じ変数を扱うときなどは、C++ における Supe::[関数名] を書く位置を意識するようにします。



# アクタ、パーシスタントレベル、サブレベルの実行順
アクタ、パーシスタントレベル、サブレベルの各Blueprintにおける、BeginPlayとEndPlayの実行順番を確認していくにあたって、BeginPlayが実行された際は、ゲームプレイ画面にメッセージを出すようにしました。

EndPlayにおいては、レベルのEndPlayが呼ばれる際に、ゲームプレイ画面にメッセージを表示することはできないので、ログに残すようにしました。

```
[A or ML or SL] -> [関数名]
```
（A = アクタ、ML = パーシスタントレベル、SL = サブレベル）
<br>

また、アクタはパーシスタントレベルに配置しました。<br><br>

ゲームプレイを開始し、各関数が呼ばれた順番を確認したところ、下図のように表示されていました。

![actorlevelorder1.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/4ad49961-332e-67a6-3fa9-7c15c70f0c5a.jpeg)

![actorlevelorder2.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3628167/cfbc65ef-6d0a-f2ec-e1a8-81a3b8564b15.jpeg)<br><br>


上図のゲームプレイ画面のメッセージにおいては、下に表示されている文字の方が早く実行されており、下図のログにおいては、上に表示されている文字の方が早く実行されています。
そのため、アクタ、パーシスタントレベル、サブレベルの各Blueprintにおける、BeginPlayとEndPlayの実行順番は、下記の順番であるということがわかりました。<br><br>

1. アクタのBeginPlay
1. パーシスタントレベルのBeginPlay
1. サブレベルのBeginPlay
1. サブレベルのEndPlay
1. アクタのEndPlay
1. パーシスタントレベルのEndPlay
<br>


BeginPlayは、**パーシスタントレベル → サブレベルの順番で呼ばれるとともに、そのレベルに配置しているアクタのBeginPlay方がレベルのBeginPlayよりも早く呼ばれる**ということがわかりました。<br><br>

またEndPlayは、**サブレベル → パーシスタントレベルの順番で呼ばれるとともに、そのレベルに配置しているアクタのBeginPlay方がレベルのBeginPlayよりも早く呼ばれる**ということがわかりました。


# 検証結果まとめ

## アクタにおけるC++、Blueprintの実行順番
1. C++のコンストラクタ
1. C++のBeginPlay（Super::BeginPlay()の前）
1. BlueprintのBeginPlay
1. C++のBeginPlay（Super::BeginPlay()の後）
1. C++のEndPlay（Super::EndPlay()の前）
1. BlueprintのEndPlay
1. C++のEndPlay（Super::EndPlay()の後）

**C++ の Super::[関数名] を呼ぶ際に、Blueprint の関数が呼ばれている**
<br>

## アクタ、パーシスタントレベル、サブレベルの実行順

アクタをパーシスタントレベルに配置した場合、

1. アクタのBeginPlay
1. パーシスタントレベルのBeginPlay
1. サブレベルのBeginPlay
1. サブレベルのEndPlay
1. アクタのEndPlay
1. パーシスタントレベルのEndPlay

BeginPlayは、**パーシスタントレベル → サブレベルの順番で呼ばれるとともに、そのレベルに配置しているアクタのBeginPlay方がレベルのBeginPlayよりも早く呼ばれる**ということがわかりました。<br>

またEndPlayは、**サブレベル → パーシスタントレベルの順番で呼ばれるとともに、そのレベルに配置しているアクタのBeginPlay方がレベルのBeginPlayよりも早く呼ばれる**ということがわかりました。
<br><br><br>



以上で検証は終了となります。
最後まで読んでいただき、ありがとうございました。


# 更新履歴
（2024年02月06日）C++ の Super::[関数名] のことを考慮した内容に修正