UE4/C++: DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam と TArray
問題
C++ コードの実装に DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam
マクロを使い、パラメーターに TArray
を入れて Delay (Blueprintノード右上に時計マークの出るアレ)を経て結果を処理できる非同期動作のデータのジェネレーターを UE4 の勉強と練習として作ってみました。しかし、不思議な事に C++ ソースコードのコンパイル(ビルド)は完了し、 UE4Editor も動作するのですが、実際にその実装を Blueprint で試すと、 Blueprint がコンパイルエラーとなり使用できない状況に遭遇しました。
// 例えばこんな動的マルチキャストデリゲートを使おうとする。 // このようにパラメーターに TArray を直接入れると Blueprint で使う段階になってから問題が起こる。 DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam( FGenerateMyDataDelegate, TArray< uint8 >, MyData );
// ↑を使ったクラスの例 UCLASS() class MyExperimental_API UAsyncTaskGenerateMyData : public UBlueprintAsyncActionBase { GENERATED_UCLASS_BODY() public: UPROPERTY( BlueprintAssignable ) FGenerateMyDataDelegate OnSuccess; UPROPERTY( BlueprintAssignable ) FGenerateMyDataDelegate OnFail; // 実際にはこのクラスを作って投げる機構なども付ける // UE4 標準の AsyncTaskDownloadImage のソースなど参考にするとよい };
Blueprint で発生するエラーは↓のようになる。
LogBlueprint: Error: [Compiler VW0_BP] Generate My Data Signature Error: The function/event 'OnSuccess_C9A93DFE4DF51C0C6C9496873C6AAC62' does not match the necessary signature - has the delegate or function/event changed? LogBlueprint: Error: [Compiler VW0_BP] Generate My Data Signature Error: The function/event 'OnFail_C9A93DFE4DF51C0C6C9496873C6AAC62' does not match the necessary signature - has the delegate or function/event changed?
他の型を与えた場合について
ちなみに、パラメーターに TArray
ではなく、代替として次のような USTRUCT
ラッパーを定義して与えると Blueprint でもコンパイルエラーが発生せずに意図通り動作する。
USTRUCT( BlueprintType )
struct MyDataWrapper
{ GENERATED_BODY()
TArray< uint8 > MyData;
};
// ラッパーを噛ませたマクロを使うと Blueprint も意図通りに動作可能になる。
DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam( FGenerateMyDataDelegate, MyDataWrapper, MyData );
また、 UTexture*
など適当なコンポーネント(のポインター)を DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam
のパラメーターへ与えた場合も Blueprint は意図通り動作する。
解決
// マクロに対して const & でパラメーターを与えれば TArray を使用し、 Blueprint も意図通りに使用可能になる。 DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam( FGenerateMyDataDelegate, const TArray<uint8>&, MyData );
なるほどー😃 C++er にはピンと来る答えです。教えて貰う前に気付けるのが真の C++er とか嫌味を言われそうですが、気にしない。