概要
Blueprint では enum のタイプ指定で foreach をするノードがありますが、同様のことを c++ で行う方法です。
サンプルコード
UENUM(BlueprintType)
enum class ETestType1 : uint8
{
TypeA,
TypeB,
TypeC,
TypeD,
};
UENUM()
enum class ETestType2 : uint8
{
Type1,
Type2,
Type3,
Type4,
TypeX100 = 100,
TypeX120 = 120,
TypeX121,
TypeX122,
TypeZero = 0,
TypeOne,
TypeTwo,
TypeThree,
};
// for ループで enum の値を LOG 出力する例.
// ETestType1.
{
const UEnum* enumPtr = FindObject<UEnum>(ANY_PACKAGE, TEXT("ETestType1"), true);
if (enumPtr != nullptr)
{
UE_LOG(LogTemp, Log, TEXT("ETestType1 num = %d"), enumPtr->NumEnums());
for (int i = 0; i < enumPtr->NumEnums(); i++)
{
ETestType1 enumValue = (ETestType1)(enumPtr->GetValueByIndex(i));
UE_LOG(LogTemp, Log, TEXT("%s = %d"), *enumPtr->GetNameByIndex(i).ToString(), (int)enumValue);
}
}
}
// ETestType2. // コード的には ↑ の ETestType1 とほぼ同じです.
{
const UEnum* enumPtr = FindObject<UEnum>(ANY_PACKAGE, TEXT("ETestType2"), true);
if (enumPtr != nullptr)
{
UE_LOG(LogTemp, Log, TEXT("ETestType2 num = %d"), enumPtr->NumEnums());
for (int i = 0; i < enumPtr->NumEnums(); i++)
{
ETestType2 enumValue = (ETestType2)(enumPtr->GetValueByIndex(i));
UE_LOG(LogTemp, Log, TEXT("%s = %d"), *enumPtr->GetNameByIndex(i).ToString(), (int)enumValue);
}
}
}
/* output result.
LogTemp: ETestType1 num = 5
LogTemp: ETestType1::TypeA = 0
LogTemp: ETestType1::TypeB = 1
LogTemp: ETestType1::TypeC = 2
LogTemp: ETestType1::TypeD = 3
LogTemp: ETestType1::ETestType1_MAX = 4
LogTemp: ETestType2 num = 13
LogTemp: ETestType2::Type1 = 0
LogTemp: ETestType2::Type2 = 1
LogTemp: ETestType2::Type3 = 2
LogTemp: ETestType2::Type4 = 3
LogTemp: ETestType2::TypeX100 = 100
LogTemp: ETestType2::TypeX120 = 120
LogTemp: ETestType2::TypeX121 = 121
LogTemp: ETestType2::TypeX122 = 122
LogTemp: ETestType2::TypeZero = 0
LogTemp: ETestType2::TypeOne = 1
LogTemp: ETestType2::TypeTwo = 2
LogTemp: ETestType2::TypeThree = 3
LogTemp: ETestType2::ETestType2_MAX = 123
*/
説明
c++ で enum to string をする手法がこちらで説明されています。
https://wiki.unrealengine.com/Enums_For_Both_C%2B%2B_and_BP
enum のタイプ名から FindObject で UEnum 型のObjetを取得し、そこから情報を取っているようで、これを参考にしました。
UEnum 型は、以下のような関数が使えます。
http://api.unrealengine.com/INT/API/Runtime/CoreUObject/UObject/UEnum/
また、ソースコードを見てみると、UEnum オブジェクトは enum の定義名の FName が Key で、int64 の値を Value として持っていることがわかります。
class COREUOBJECT_API UEnum : public UField
{
/*略*/
protected:
/** List of pairs of all enum names and values. */
TArray<TPair<FName, int64>> Names;
UEnum には GetValueByIndex() や GetNameByIndex() などがあるので、これらを使ってforeachを実現しています。
注意
- UEnum オブジェクトから情報を取るには、enum に UENUM() をつけて、エンジンに対して明示する必要があります。UENUM() をつけていないと FindObject で nullptr が返ってきます。
- UEnum 内の情報には、定義したもの以外に、最後に _MAX が自動的に追加されます。ETestType2 のログを見てもらえればわかりますが、最後の定義 +1 がMaxになるわけではないようです。
動作確認環境
UnrealEngine 4.20.2
Visual Studio Community 2015