【UE5】BlueprintImplementableEvent と BlueprintNativeEvent の違いについて
プログラマーの尾関です。
今回は、似た概念である BlueprintImplementableEvent と BlueprintNativeEvent の違いについてまとめたいと思います。
BlueprintImplementableEvent と BlueprintNativeEvent の共通点
この2つの概念に共通しているのは以下のことです。
- Blueprintで実装された関数をC++で呼び出したい
- そのために C++で定義した UFUNCTIONの指定子として記述することで、Blueprintでオーバーライドまたは実装可能となる
BlueprintImplementableEventの実装例
例えば、BlueprintImplementableEventのヘッダファイルでの定義例は以下のとおりです。
// テレポート開始.
UFUNCTION(BlueprintImplementableEvent, DisplayName = "テレポート開始", Category = "VRPawn")
void OnRThumbUpPressed();BlueprintImplementableEventは宣言のみで実体はありません。ただ、Unreal EngineがBP側の実体があれば自動でバインドしてくるため、実体がなくてもエラーとはならないためC++からも安心して呼び出せます。
具体的にはBlueprintグラフで右クリックして、作成した関数名を指定するとイベントが作れます。

そしてイベントとしてグラフを組んでいきます。

その他、クリックイベントの呼び出し処理など、WidgetBlueprintで記述した方が簡潔に実装できるものを Blueprintで行うためにBlueprintImplementableEventはよく使われるかなと思います。
BlueprintNativeEventの実装例
BlueprintNativeEventは、C++側では以下のように定義します。
// スライダーの値を取得.
UFUNCTION(BlueprintNativeEvent,Category = "HUD3D")
float OnGetSliderValue() const;
virtual float OnGetSliderValue_Implementation() const { return 0.f; };定義した関数名とは別に「XXX_Implementation()」という関数が実装されています。これはBlueprintImplementableEventと異なり、C++側で実体の定義が可能です。ただ「XXX_Implementation()」を未実装のままにしておくとC++からの呼び出し時にリンカエラーとなるため注意が必要です。そのため個人的にはBPで実装予定であってもC++側で仮でもいいので実装しておくことをおすすめします。
これをBlueprintで実装する場合、イベントではなく「オーバーライド関数」として実装します。
“オーバーライド可能” とある部分の「オーバーライド」というドロップダウンを選んで、定義した関数で検索。

Widgetに設定されている値を取得する関数を実装しました。

なお「戻り値のある関数」はBlueprintNativeEventでないと実装できないので、Get関数を作りたい場合は必然的にこちらで実装することになると思います。
BlueprintImplementableEvent と BlueprintNativeEvent の違い
ではこの2つの違いの説明…ですが、共通点の紹介ですでに異なる点を紹介してしまったので、ここでは簡単にまとめるのみとします。
違いをまとめると、大まかに以下の通りとなると思います。
| UFUNCTION指定子 | 用途 | 注意点 |
|---|---|---|
| BlueprintImplementableEvent | ・C++からBPの処理を呼び出したい ・中身の実装はBPに任せたい (後回しにしたい) | ・戻り値のある関数は定義できない |
| BlueprintNativeEvent | ・C++からBPの処理を呼び出したい ・C++側にデフォルトの実装を定義したい ・関数に戻り値を持たせたい ・Const関数にしたい | ・「XXX_Implementation()」やBP側の実装がない状態で 呼び出すとリンカエラーとなる |
どちらにも言えることとしては、C++とBPで実装を分担してお互いに連携したい場合に使うUFUNCTION指定子であると言えます。
BlueprintCallable・BlueprintPureとの違い
上記の説明の補足として、BlueprintCallable・BlueprintPureとの違いについて比較してみます。
BlueprintCallable・BlueprintPureの大きな特徴しては「C++側でしか実装できない(=BP側で実装やオーバーライドできない)」ということです。C++で実装してそれをBP側で呼び出す、といった一方通行の処理の流れであればBlueprintCallable・BlueprintPureで問題ないこととなります。
改めて、これら4つのUFUNCTION指定子をまとめると以下のとおりです。
| UFUNCTION指定子 | 実装場所 | Blueprintから呼び出せる | Blueprintでオーバーライド可能 | 戻り値 |
|---|---|---|---|---|
| BlueprintCallable | C++ のみ | ◯ | ✘ | ◯ |
| BlueprintPure | C++ のみ | ◯ (副作用なし) | ✘ | ◯ |
| BlueprintImplementableEvent | Blueprint のみ | ✘ (イベントとして呼び出す) | ◯ (イベントとして実装) | ✘ |
| BlueprintNativeEvent | C++ or Blueprint | ✘ (イベントとして呼び出す) | ◯ (オーバーライドで実装) | ◯ |
おしまい
以上、BlueprintImplementableEvent と BlueprintNativeEvent の違いについてでした。
この情報が UFUNCTION の理解にお役立てれば幸いです。

