【UE4】クラスからUPROPERTYの値を取得する方法について


概要

UPROPERTY を付与した変数は UE の UProperty クラスとして情報が格納されます。
変数名やその値が格納されております。
先日調べたメモをまとめておきます。

取得する方法

UE4 に取得したいクラスのメンバー変数名を渡すことで、
そのUPropertyを取得するメソッドがあるのでそちらを使います。

Foo.cpp
// 取得したいクラスの StaticClass と、
// そのクラスに宣言したUPROPERTY付きの変数名を引数で渡します.
UProperty* Property = FindField<UProperty>( UMyClass::StaticClass(), TEXT("FieldName"));

このようにすることで任意のメンバー変数を取得できます。

また、取得した UProperty クラスは型ごとに継承されたクラスとなってます。
たとえば

Sample.h

USTRUCT()
struct FStatus
{
:
    UPROPERTY()
    int32 HitPoint;
:
};

UCLASS()
class AHuman : AActor
{
public:
:
    UPROPERTY()
    FStatus* Property;
};

というクラスから値を取得するとします。
Humanがもつ Property は struct の変数ですので UStructProperty クラスになってます。

キャストしてその型の持つ値を取得できます。

UStructProperty* StructProperty = Cast<UStructProperty>( Property );

// UStructPropertyが持つstruct情報を取得します.
// 構造体が持つメンバー変数 HitPoint が取得できる想定です.
UField* Field = StructProperty->Struct->Children;

クラスが持つUPROPERTYを全て取得する

最後に応用編です。
UFieldクラスはメンバー変数 Next に、次の UField のポインタを持ってます。
これをたどることで全ての値を取得することができます。

Sample

// 適当な構造体を表します.
USTRUCT()
struct FMyStruct
{
:
    UROPERTY()
    int32 Value1;

    UPROPERTY()
    int32 Value2;
:
};

// 適当なクラスを表します.
UCLASS()
class UMyClass : UObject
{
:
    UPROPERTY()
    FMyStruct* MyStruct;
:
};

// UMyClass に含まれる変数を取得します.
UProperty* Property = FindField<UProperty>(UMyClass::StaticClass(), TEXT("MyStruct"));

// 構造体UPropertyへキャストします.
UStructProperty* StructProperty = Cast<UStructProperty>( Property );

// その構造体が持つメンバー変数を順番に取得します.
UField Field = StructProperty->Struct->Children;

// Field(MyStruct)が持つメンバー変数を取得します.
while ( Field != nullptr )
{
:
:
    // FMyStruct の Value1、Value2 の順にループします.
:
:
    // 次の要素を受け取ります.
    Field = Field->Next;
}

まとめ

ゲーム側の処理ではあまり使わないと思いますが、
デバッグ用の機能で使えると思います
私はデバッグ機能とドキュメントの作成時に変数名を抽出するために使いました。