【UnLua】在 Lua 中定义 UE 反射类型
用法
- 启动编辑器时遍历 Defines 目录下 lua 脚本来加载 UE 反射类型(开个临时的 Lua VM 即可)
- 直接像
-- define a uenum in lua
UEnum.EEnumGuestSomethingElse {Value1 = 1;Value2 = 2;
}-- use it like a native uenum
UnLua.Log(UE.EEnumGuestSomethingElse.Value2)UClass { Config = "Game" }.
MoviePipelineExampleRuntimeExecutor(UE.MoviePipelinePythonHostExecutor, UE.IXXXInteface) {activeMoviePipeline = UE.UProperty {};exampleArray = UE.TArray(str);exampleDict = UE.TMap(str, bool);on_map_load = UE.UFunction {override = true;params = { };}
}UStruct { BlueprintType = true }.
FAnimCurveCreationData(UE.FMovementSettings_Stance) {FrameNumber = UProperty(UE.int32) { DisplayName = "Frame Number" };CurveValue = UProperty(UE.float);exampleArray = UProperty(UE.TArray, "");exampleDict = UProperty(UE.TMap, "", false);
}
====== UEnum ======
C++
UENUM(BlueprintType)
enum class ETest : uint8
{Walking,Running,Sprinting,ALS_MAX UMETA(DisplayName="ALS MAX")
};
Test.generated.h
#include "UObject/ObjectMacros.h"
#include "UObject/ScriptMacros.h"#define FOREACH_ENUM_ETEST(op) \op(ETest::Walking) \op(ETest::Running) \op(ETest::Sprinting) \op(ETest::ALS_MAX)enum class ETest : uint8;
template<> struct TIsUEnumClass<ETest> { enum { Value = true }; };
template<> LYRAGAME_API UEnum* StaticEnum<ETest>();
Test.gen.cpp
- 生成代码入口 FNativeClassHeaderGenerator::ExportGeneratedEnumInitCode
- 构造 UEnum 入口 UECodeGen_Private::ConstructUEnum
- 构造时机:static 注册,所以 C++ 启动时
void EmptyLinkFunctionForGeneratedCodeTest() {}
// Cross Module ReferencesLYRAGAME_API UEnum* Z_Construct_UEnum_LyraGame_ETest();UPackage* Z_Construct_UPackage__Script_LyraGame();
// End Cross Module Referencesstatic FEnumRegistrationInfo Z_Registration_Info_UEnum_ETest;static UEnum* ETest_StaticEnum(){if (!Z_Registration_Info_UEnum_ETest.OuterSingleton){Z_Registration_Info_UEnum_ETest.OuterSingleton = GetStaticEnum(Z_Construct_UEnum_LyraGame_ETest, Z_Construct_UPackage__Script_LyraGame(), TEXT("ETest"));}return Z_Registration_Info_UEnum_ETest.OuterSingleton;}template<> LYRAGAME_API UEnum* StaticEnum<ETest>(){return ETest_StaticEnum();}struct Z_Construct_UEnum_LyraGame_ETest_Statics{static const UECodeGen_Private::FEnumeratorParam Enumerators[];
#if WITH_METADATAstatic const UECodeGen_Private::FMetaDataPairParam Enum_MetaDataParams[];
#endifstatic const UECodeGen_Private::FEnumParams EnumParams;};const UECodeGen_Private::FEnumeratorParam Z_Construct_UEnum_LyraGame_ETest_Statics::Enumerators[] = {{ "ETest::Walking", (int64)ETest::Walking },{ "ETest::Running", (int64)ETest::Running },{ "ETest::Sprinting", (int64)ETest::Sprinting },{ "ETest::ALS_MAX", (int64)ETest::ALS_MAX },};
#if WITH_METADATAconst UECodeGen_Private::FMetaDataPairParam Z_Construct_UEnum_LyraGame_ETest_Statics::Enum_MetaDataParams[] = {{ "ALS_MAX.DisplayName", "ALS MAX" },{ "ALS_MAX.Name", "ETest::ALS_MAX" },{ "BlueprintType", "true" },{ "ModuleRelativePath", "Common/Defines/Test.h" },{ "Running.Name", "ETest::Running" },{ "Sprinting.Name", "ETest::Sprinting" },{ "Walking.Name", "ETest::Walking" },};
#endifconst UECodeGen_Private::FEnumParams Z_Construct_UEnum_LyraGame_ETest_Statics::EnumParams = {(UObject*(*)())Z_Construct_UPackage__Script_LyraGame,nullptr,"ETest","ETest",Z_Construct_UEnum_LyraGame_ETest_Statics::Enumerators,UE_ARRAY_COUNT(Z_Construct_UEnum_LyraGame_ETest_Statics::Enumerators),RF_Public|RF_Transient|RF_MarkAsNative,EEnumFlags::None,(uint8)UEnum::ECppForm::EnumClass,METADATA_PARAMS(Z_Construct_UEnum_LyraGame_ETest_Statics::Enum_MetaDataParams, UE_ARRAY_COUNT(Z_Construct_UEnum_LyraGame_ETest_Statics::Enum_MetaDataParams))};UEnum* Z_Construct_UEnum_LyraGame_ETest(){if (!Z_Registration_Info_UEnum_ETest.InnerSingleton){UECodeGen_Private::ConstructUEnum(Z_Registration_Info_UEnum_ETest.InnerSingleton, Z_Construct_UEnum_LyraGame_ETest_Statics::EnumParams);}return Z_Registration_Info_UEnum_ETest.InnerSingleton;}struct Z_CompiledInDeferFile_FID_Lyra_Source_LyraGame_Common_Defines_Test_h_Statics{static const FEnumRegisterCompiledInInfo EnumInfo[];};const FEnumRegisterCompiledInInfo Z_CompiledInDeferFile_FID_Lyra_Source_LyraGame_Common_Defines_Test_h_Statics::EnumInfo[] = {{ ETest_StaticEnum, TEXT("ETest"), &Z_Registration_Info_UEnum_ETest, CONSTRUCT_RELOAD_VERSION_INFO(FEnumReloadVersionInfo, 2142314138U) },};static FRegisterCompiledInInfo Z_CompiledInDeferFile_FID_Lyra_Source_LyraGame_Common_Defines_Test_h_3878057739(TEXT("/Script/LyraGame"),nullptr, 0,nullptr, 0,Z_CompiledInDeferFile_FID_Lyra_Source_LyraGame_Common_Defines_Test_h_Statics::EnumInfo, UE_ARRAY_COUNT(Z_CompiledInDeferFile_FID_Lyra_Source_LyraGame_Common_Defines_Test_h_Statics::EnumInfo));
Python
- 创建入口 FPythonGeneratedEnumBuilder::RegisterDescriptors
- 创建时机 uenum -> GenerateEnum
@unreal.uenum()
class PyTestColor(unreal.EnumBase):RED = unreal.uvalue(1, meta={"DisplayName": "Red (255, 0, 0)"})GREEN = unreal.uvalue(2)BLUE = unreal.uvalue(3)
====== UStruct ======
C++
USTRUCT(BlueprintType)
struct FMovementSettings_Stance
{GENERATED_BODY()
public:UPROPERTY(BlueprintReadWrite, EditAnywhere, meta=(DisplayName="Standing"))FMovementSettings Standing = {};UPROPERTY(BlueprintReadWrite, EditAnywhere, meta=(DisplayName="Crouching"))FMovementSettings Crouching = {};
};USTRUCT(BlueprintType)
struct FAnimCurveCreationData : FMovementSettings_Stance
{GENERATED_BODY()
public:UPROPERTY(BlueprintReadWrite, EditAnywhere, meta=(DisplayName="Frame Number"))int32 FrameNumber = {};UPROPERTY(BlueprintReadWrite, EditAnywhere, meta=(DisplayName="Curve Value"))float CurveValue = {};
};
void ConstructUScriptStruct(UScriptStruct*& OutStruct, const FStructParams& Params)
{UObject* (*OuterFunc)() = Params.OuterFunc;UScriptStruct* (*SuperFunc)() = Params.SuperFunc;UScriptStruct::ICppStructOps* (*StructOpsFunc)() = (UScriptStruct::ICppStructOps* (*)())Params.StructOpsFunc;UObject* Outer = OuterFunc ? OuterFunc() : nullptr;UScriptStruct* Super = SuperFunc ? SuperFunc() : nullptr;UScriptStruct::ICppStructOps* StructOps = StructOpsFunc ? StructOpsFunc() : nullptr;if (OutStruct){return;}UScriptStruct* NewStruct = new(EC_InternalUseOnlyConstructor, Outer, UTF8_TO_TCHAR(Params.NameUTF8), Params.ObjectFlags) UScriptStruct(FObjectInitializer(), Super, StructOps, (EStructFlags)Params.StructFlags, Params.SizeOf, Params.AlignOf);OutStruct = NewStruct;ConstructFProperties(NewStruct, Params.PropertyArray, Params.NumProperties);NewStruct->StaticLink();#if WITH_METADATAAddMetaData(NewStruct, Params.MetaDataArray, Params.NumMetaData);
#endif
}
Python
class MoviePipelineExampleRuntimeExecutor(unreal.MoviePipelinePythonHostExecutor):# Declare the properties of the class here. You can use basic# Python types (int, str, bool) as well as unreal properties.# You can use Arrays and Maps (Dictionaries) as wellactiveMoviePipeline = unreal.uproperty(unreal.MoviePipeline)exampleArray = unreal.Array(str) # An array of stringsexampleDict = unreal.Map(str, bool) # A dictionary of strings to bools.# Constructor that gets called when created either via C++ or Python# Note that this is different than the standard __init__ function of Pythondef _post_init(self):# Assign default values to properties in the constructorself.activeMoviePipeline = Noneself.exampleArray.append("Example String")self.exampleDict["ExampleKey"] = True