くーこのプログラマメモ

UE4などゲーム開発に関するメモ

構造体のMake/BreakノードのNative実装

使用バージョン:UE4.24.2

はじめに

USTRUCTメタデータを使用することで構造体のMake/Breakノードで指定の関数を呼び出すことができるようになります。 このときに指定する関数は、UBlueprintFunctionLibrary等でBlueprintCallableとしてUFUNCTION定義したものになります。

Makeノード

メタデータHasNativeMake=[関数パス([モジュール名].[クラス名].[関数名])]を設定します。

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"

#include "Example.generated.h"


/**
 * Makeノード実装
 */
USTRUCT(BlueprintType
    , meta = (HasNativeMake="Example.ExampleFunctionLibrary.MakeExample")
struct FExample
{
    GENERATED_BODY()

    UPROPERTY()
    int32       Value = 0;
};


UCLASS()
class UExampleFunctionLibrary : public UBlueprintFunctionLibrary
{
    GENERATED_BODY()
public:
    /** FExampleのMakeノード用関数 */
    UFUNCTION(BlueprintPure, meta = (NativeMakeFunc))
    static FExample MakeExample()
    {
        FExample Example = { 1 };
        return Example;
    }
};

Breakノード

メタデータHasNativeBreak=[関数パス([モジュール名].[クラス名].[関数名])]を設定します。

#pragma once

#include "CoreMinimal.h"
#include "Kismet/BlueprintFunctionLibrary.h"

#include "Example.generated.h"


/**
 * Breakノード実装
 */
USTRUCT(BlueprintType
    , meta = (HasNativeBreak= "Example.ExampleFunctionLibrary.BreakExample"))
struct FExample
{
    GENERATED_BODY()

    UPROPERTY()
    int32       Value = 0;
};


UCLASS()
class UExampleFunctionLibrary : public UBlueprintFunctionLibrary
{
    GENERATED_BODY()
public:
    /** FExampleのBreakノード用関数 */
    UFUNCTION(BlueprintPure, meta = (NativeBreakFunc))
    static void BreakExample(const FExample& InTarget, int32& Value)
    {
        Value = InTarget.Value;
    }
};

最後に

通常は、プロパティをブループリント非公開の場合はMake/Breakノード自体がノードリストに表示されませんが、この方法を利用した場合はノードリストに表示され使用することができます。

個人的な利用方法として、構造体をハンドルとして利用する際にプロパティをブループリント非公開にし、デフォルトのMake/Breakノードを使用せず、必要であればMakeノードの実装や関数を用意し必要最低限の機能だけを利用できるようにしています。

修正

  • 関数パスのクラス名にプレフィックスついた状態だと、PythonScriptPluginを利用した際にエディタ起動時にREPORT_PYTHON_GENERATION_ISSUE()が発生してしまうのもあり、エンジン内を確認し該当箇所を修正いたしました。

    UExampleFunctionLibrary -> ExampleFunctionLibrary