デリゲートを受け取る引数を省略可能にする

More than 1 year has passed since last update.


デリゲートは省略できない?

デリゲートを引数にする場合、本来であれば省略することは出来ません。

例えば、以下の様な関数を作ったとします。

DECLARE_DYNAMIC_DELEGATE(FMyDelegate);

UCLASS()
class MYPROJECT_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()

UFUNCTION(BlueprintCallable, Category = "MyProject")
static void MyFunc(FMyDelegate Event) {}

};

この時、引数 Event にはデリゲートを指定しないとブループリントのコンパイルでエラーが発生します。

OptionDelegate.png

これを回避するためにデフォルト引数を指定すれば出来るのでは?とも思いましたが、C++ でコンパイルエラーが発生して、デリゲートにデフォルト引数を指定することは出来ませんでした。

    // Missing ')' in Function declaration specifier でダメ

UFUNCTION(BlueprintCallable, Category = "MyProject", meta=(Event= FMyDelegate()))
static void MyFunc(FMyDelegate Event) {}

// C++ Default parameter not parsed: Event "FMyDelegate()" でダメ
UFUNCTION(BlueprintCallable, Category = "MyProject")
static void MyFunc(FMyDelegate Event = FMyDelegate()) {}


デリゲートを省略するためには?

では、どうすればデリゲートを省略できるのか?

それは、

「引数を構造体化すること」

です。

先ほどの関数の定義を以下のように修正します。


// デリゲート
DECLARE_DYNAMIC_DELEGATE(FMyDelegate);

// 引数構造体
USTRUCT(BlueprintType)
struct FMyEvent
{
GENERATED_BODY()

// 省略したいデリゲート
UPROPERTY(BlueprintReadWrite)
FMyDelegate Delegate;

FMyEvent()
: Delegate()
{
}

};

UCLASS()
class MYPROJECT_API UMyBlueprintFunctionLibrary : public UBlueprintFunctionLibrary
{
GENERATED_BODY()

// 引数構造体を引数とする。
UFUNCTION(BlueprintCallable, Category = "MyProject")
static void MyFunc(FMyEvent Event) {}

};

こうすることで、引数 Event に何も指定しなくても、コンパイルエラーが出ることはなくなります。

(指定しない場合は、構造体のコンストラクタで初期化された値が使われます。)

OptionDelegate2.png

引数を指定したい場合は、ピンアクションの「Promote to Variable」で引数 Event のピンを展開すれば……

OptionDelegate4.png

この通り、デリゲートを指定することが出来るようになります。

(この状態で引数を指定しなかった場合は、ブループリントでコンパイルエラーが発生します。)

OptionDelegate3.png

この方法は、デリゲート以外にも「デフォルト引数で初期化出来ないものすべて」に対して使うことが出来ます。