#memo

indiedev太郎

UnrealC++のデリゲート、イベントについて

UE4のデリゲート関連、なんかいろいろあって混乱しているのでまとめる
元ネタのC#UEC++、BPエディタでの使用について確認していく


C#のデリゲート

UE4のデリゲートはC#の物を元にしているっぽいのでそちらを軽く確認しておく

シングルキャストデリゲート

delegate void DelegateA();
DelegateA a = hogeA.A;
a();
  • ローカル変数でも宣言できる
  • static関数、クラスメソッド、ラムダ式シグネチャさえ一致すればなんでもいける

マルチキャストデリゲート

a += hogeB; 
  • 初期化済みのデリゲートに対して+=演算子(combine())で関数を追加することができる
  • 追加された時点でマルチキャストデリゲートとなる
  • 代入した関数順に呼び出される
  • C#のデリゲートは全てマルチキャスト化できる

イベント

  • クラスメンバでのみ宣言可能
  • 外部クラスからは+=または-=演算子しか使えない


UnrealC++のデリゲート

Unreal Engine | デリゲート

UnrealC++ではデリゲートが用意されていて、用途によって数種類のマクロが用意されている

通常(C++内のみ) 動的(エディタに公開)
シングルキャスト DECLARE_DELEGATE DECLARE_DYNAMIC_DELEGATE
マルチキャスト DECLARE_MULTICAST_DELEGATE DECLARE_DYNAMIC_MULTICAST_DELEGATE
イベント DECLARE_EVENT -

通常・動的の違い

  • 動的のマクロはシリアル化される、要はBPエディタでも扱えるようになる
  • 動的な方が遅い

通常シングルキャストデリゲート

代入できる数 一つ
戻り値
ペイロード
BPでの見え方 アクセス不可
代入 Bind(), BindUObject()...
実行 Execute(), ExecuteIfBound()...

動的シングルキャストデリゲート

代入できる数 一つ
戻り値 不可
ペイロード 不可
BPでの見え方 Delegate型の変数
代入 BindDynamic()...
実行 Execute(), ExecuteIfBound()...

通常マルチキャストデリゲート

代入できる数 複数
戻り値 不可
ペイロード
BPでの見え方 アクセス不可
代入 Add(), AddUObject()...
実行 Broadcast()
備考 実行順は不定

動的マルチキャストデリゲート

代入できる数 複数
戻り値 不可
ペイロード 不可
BPでの見え方 イベントディスパッチャー
代入 AddDynamic()
実行 Broadcast()

通常イベント

代入できる数 複数
戻り値 不可
ペイロード
BPでの見え方 アクセス不可
代入 Add(), AddUObject()...
実行 Broadcast()
備考 Broadcast()等一部メソッドは宣言クラス内からのみアクセス可

外部クラスからBroadcast()出来ないのがEventってドキュメントに書いてるけど(C#のEventにちかい)、実装クラスでイベントがpublic指定子だったり参照返してもらったりで普通に外部クラスからも呼べちゃえるきがする

Unreal Engine | 動的デリゲート
Unreal Engine | イベント


BPエディタでのデリゲート

イベントノード
https://i.gyazo.com/54de1c6f05b388080f139f791132f66a.png

  • 戻り値がvoidの関数のエントリーノード
  • C#, UE4C++のイベントとは全く関係がない
  • ノードの右上の赤い■からDelegate型のピンが伸びる、これをシグネチャが一致しているDelegate型変数やイベントディスパッチャーのbindノードにつなぐことが出来る

Unreal Engine | イベント


Delegate
https://i.gyazo.com/2580e48437ccd74d94ebaa7a4bd30efc.png

  • UnrealC++でいうところの動的シングルキャストデリゲート
  • C++で動的シングルキャストデリゲートとして実装されているメンバに対して、UPROPERTY(BlueprintReadWrite)が設定されている時にGet、Setノードよりアクセスが出来る
  • エディタ内からはこのようなDelegate型の変数を作成することはできない
  • エディタからこのデリゲートを実行したいなら専用の関数を実装する必要がある(あるいは適当なイベントディスパッチャーにbindする)
C++ BP
関数(イベント)の追加 Bind() Set()
デリゲートの実行 Excute() -


イベントディスパッチャー
https://i.gyazo.com/d5442903262ae8c2469363bdadf5e633.png

  • UnrealC++でいうところの動的マルチキャストデリゲート
  • C++で動的マルチキャストデリゲートとして宣言した変数にUPROPERTY(BlueprintAssignable)が指定されてるさい、その変数名がイベントディスパッチャー欄に表示される
  • UPROPERTYにBlueprintCallableを指定すると、エディタ内でCallイベントノードを使用できるようになる
C++ BP
関数(イベント)の追加 Add() Bind()
デリゲートの実行 Broadcast() Call()

Unreal Engine | BlueprintAssignable
Unreal Engine | BlueprintCallable
UE4 C++でイベント/イベントディスパッチャーを作る - GameProgrammar's Night