UE4 C++でイベント/イベントディスパッチャーを作る
UE C++には、デリゲートが用意されています。デリゲートとは簡単に説明しますと、メソッド・関数などを変数に保存して、任意のタイミングで呼び出せる仕組みです。詳しくはググってください。
このデリゲートの中に、BP上でイベント/イベントディスパッチャーとして扱われる仕組みがありますので紹介します。
イベントディスパッチャー
良く使うであろうイベントディスパッチャーの実装から先に説明します。
動的マルチキャストデリゲートを実装するとBP上ではイベントディスパッチャーとして扱われます。
実装例
// 動的マルチキャストデリゲート(イベントディスパッチャー)の宣言 DECLARE_DYNAMIC_MULTICAST_DELEGATE(FMyActorOnEventDispather); UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent)) class UMyActorComponent : public UActorComponent { GENERATED_BODY() virtual void TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) override; public: // 動的マルチキャストデリゲート(イベントディスパッチャー)の定義 UPROPERTY(BlueprintAssignable, Category="MyActor") FMyActorOnEventDispather OnEventDispather; }; void UMyActorComponent::TickComponent( float DeltaTime, ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction ) { OnEventDispather.Broadcast(); // イベントディスパッチャーをCallする }
DECLARE_DYNAMIC_MULTICAST_DELEGATEマクロを使って、イベントディスパッチャー用のクラスを作ります。()の中がクラス名となります。
その作ったクラスのプロパティをクラス内で定義し、Assingnableに設定します。そうすることでBPで作ったイベントをバインドすることができます。
イベントディスパッチャーとして宣言した変数のBroadcastメソッドを呼ぶことが、イベントディスパッチャーをCallすることと同じことになります。
BP上でMyActorComponentをActorに追加して、使った例は以下の通り。
イベントディスパッチャーとして使用できています。
また、イベントディスパッチャーで引数を取る場合は、引数ありの宣言マクロを使います。
// 1つ引数を取り、型がboolで引数名がbSuccess のイベントディスパッチャー宣言 DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FMyActorOnEventDispather, bool, bSuccess);
引数は8個まで取ることができます。引数の数を増やしたら、OneParamのOneの部分を引数の数の英語に変えます*1。
戻り値はBPのイベントディスパッチャー同様に扱えません。
イベント
BPでのイベントに相当するのは、動的デリゲートです。デリゲートの中にイベントもありますが別ものです。名称がまぎらわしいですね。
docs.unrealengine.com
実装例
実装の仕方は、動的マルチキャストとほぼ同じです。
DECLARE_DYNAMIC_MULTICAST_DELEGATEマクロではなく、DECLARE_DYNAMIC_DELEGATEを使います。
// 動的デリゲート(イベント)の宣言 DECLARE_DYNAMIC_DELEGATE(FMyActorOnEvent); UCLASS(ClassGroup=(Custom), meta=(BlueprintSpawnableComponent)) class UMyActorComponent : public UActorComponent { GENERATED_BODY() // BPから動的デリゲート(イベント)を呼び出すメソッド UFUNCTION(BluprintCallable, Category="MyActor") void CallOnEvent(); public: // 動的デリゲート(イベント)の定義 UPROPERTY(BlueprintReadWrite, Category="MyActor") FMyActorOnEvent OnEvent; }; void UMyActorComponent::CallOnEvent() { OnEvent.ExecuteIfBound(); }
イベントディスパッチャー実装と違うのは、イベントとして宣言した変数にBlueprintAssignableが使えません。代わりに通常の変数と同じようにBluprintReadWrite・BlueprintReadOnlyなどを使います。
また、イベントの呼び出しは、Execute・ExecuteIfBoundメソッドのどちらかを使いますが、それらのメソッドはBPから直接呼ぶことができませんので、BP上から呼べるようにメソッド(CallOnEventメソッド)を別途追加します。
BlueprintReadWriteで宣言すると、BP上のイベントをバインドできるようになります。また、イベントディスパッチャーにバインドすることも可能です。
引数を取る時も、イベントディスパッチャー実装と同じです。
DECLARE_DYNAMIC_DELEGATE_OneParam(FMyActorOnEvent, bool, bSuccess);
*1:2個ならTwoなど