概要
この記事では、C++のコンストラクタ、BeginPlay、EndPlayと、BlueprintのBeginPlay、EndPlayがどのような順番で呼ばれているのかを、アクタを用いて検証します。
また、アクタ、パーシスタントレベル、サブレベルのBlueprintおける、各関数の実行順番も検証します。
結果だけご覧になりたい方は、こちらをご覧ください。
この記事の主な対象者
- Unreal Engine初心者の方
前提知識
Unreal Engineでは、C++にデストラクタはありません。
またBlueprintには、コンストラクタとデストラクタはありません。(ただし、UMGにはコンストラクタとデストラクタがあります。)
アクタにおけるC++、Blueprintの実行順番
アクタにおけるC++、Bluepritnの実行順番を確認していくにあたって、最初に、筆者がC++で作成したクラスを親クラスに設定したアクタのBlueprintを作成しました。
また、C++とBlueprintの各関数(C++のコンストラクタ、C++とBlueprintのBeginPlay、EndPlay)が呼び出されたときに、ゲームプレイ画面に下の形式でメッセージを表示するようにしました。
[C+ or BP] -> [関数名]
(C+ = C++、BP = Blueprint)
また、C++ の BeginPlay では Super::BeginPlay() の前と後にメッセージを表示する処理を書き、前だったら「C+ -> BeginPlay before Super」、後だったら「C+ -> BeginPlay after Super」と表示するようにしました。
EndPlayにおいても、同様のことを行いました。
アクタをスポーンした直後に、スポーンしたアクタをDestroyする処理を行うことで、各関数の実行順番を確認したところ、下図のように表示されていました。
上図において、下に表示されている文字の方が早く実行されているので、C++とBlueprintの各関数(C++のコンストラクタ、C++とBlueprintのBeginPlay、EndPlay)の実行順番は、下記の順番であるということがわかりました。
- C++のコンストラクタ
- C++のBeginPlay(Super::BeginPlay()の前)
- BlueprintのBeginPlay
- C++のBeginPlay(Super::BeginPlay()の後)
- C++のEndPlay(Super::EndPlay()の前)
- BlueprintのEndPlay
- C++のEndPlay(Super::EndPlay()の後)
C++ の Super::[関数名] を呼ぶ際に、Blueprint の関数が呼ばれているということがわかったので、C++とBlueprintのBeginPlayやEndPlayで同じ変数を扱うときなどは、C++ における Supe::[関数名] を書く位置を意識するようにします。
アクタ、パーシスタントレベル、サブレベルの実行順
アクタ、パーシスタントレベル、サブレベルの各Blueprintにおける、BeginPlayとEndPlayの実行順番を確認していくにあたって、BeginPlayが実行された際は、ゲームプレイ画面にメッセージを出すようにしました。
EndPlayにおいては、レベルのEndPlayが呼ばれる際に、ゲームプレイ画面にメッセージを表示することはできないので、ログに残すようにしました。
[A or ML or SL] -> [関数名]
(A = アクタ、ML = パーシスタントレベル、SL = サブレベル)
また、アクタはパーシスタントレベルに配置しました。
ゲームプレイを開始し、各関数が呼ばれた順番を確認したところ、下図のように表示されていました。
上図のゲームプレイ画面のメッセージにおいては、下に表示されている文字の方が早く実行されており、下図のログにおいては、上に表示されている文字の方が早く実行されています。
そのため、アクタ、パーシスタントレベル、サブレベルの各Blueprintにおける、BeginPlayとEndPlayの実行順番は、下記の順番であるということがわかりました。
- アクタのBeginPlay
- パーシスタントレベルのBeginPlay
- サブレベルのBeginPlay
- サブレベルのEndPlay
- アクタのEndPlay
- パーシスタントレベルのEndPlay
BeginPlayは、パーシスタントレベル → サブレベルの順番で呼ばれるとともに、そのレベルに配置しているアクタのBeginPlay方がレベルのBeginPlayよりも早く呼ばれるということがわかりました。
またEndPlayは、サブレベル → パーシスタントレベルの順番で呼ばれるとともに、そのレベルに配置しているアクタのBeginPlay方がレベルのBeginPlayよりも早く呼ばれるということがわかりました。
検証結果まとめ
アクタにおけるC++、Blueprintの実行順番
- C++のコンストラクタ
- C++のBeginPlay(Super::BeginPlay()の前)
- BlueprintのBeginPlay
- C++のBeginPlay(Super::BeginPlay()の後)
- C++のEndPlay(Super::EndPlay()の前)
- BlueprintのEndPlay
- C++のEndPlay(Super::EndPlay()の後)
C++ の Super::[関数名] を呼ぶ際に、Blueprint の関数が呼ばれている
アクタ、パーシスタントレベル、サブレベルの実行順
アクタをパーシスタントレベルに配置した場合、
- アクタのBeginPlay
- パーシスタントレベルのBeginPlay
- サブレベルのBeginPlay
- サブレベルのEndPlay
- アクタのEndPlay
- パーシスタントレベルのEndPlay
BeginPlayは、パーシスタントレベル → サブレベルの順番で呼ばれるとともに、そのレベルに配置しているアクタのBeginPlay方がレベルのBeginPlayよりも早く呼ばれるということがわかりました。
またEndPlayは、サブレベル → パーシスタントレベルの順番で呼ばれるとともに、そのレベルに配置しているアクタのBeginPlay方がレベルのBeginPlayよりも早く呼ばれるということがわかりました。
以上で検証は終了となります。
最後まで読んでいただき、ありがとうございました。
更新履歴
(2024年02月06日)C++ の Super::[関数名] のことを考慮した内容に修正