すのはら荘春原庄的秋

UE4反射编程

DaiMQiu·2022-05-09 22:42·2053 次阅读

UE4反射编程

UE4反射编程#

获取类名称和类标记#

Copy
//通过反射获得类名和属性变量 UStudent* Student = NewObject<UStudent>(); UClass* StudentClass = Student->GetClass(); //获取类名称 FString ClassName = StudentClass->GetName(); UE_LOG(LogTemp, Warning, TEXT("Student's classname is %s, Student's superclassname is %s"), *ClassName, *StudentClass->GetSuperClass()->GetName()); //获取类标记 EClassFlags ClassFlags = StudentClass->ClassFlags; UE_LOG(LogTemp, Warning, TEXT("Student's classFlag is %x"), ClassFlags);

获得类的属性#

Copy
//获得类属性,其中是一个链表存储的 for(FProperty* Property = StudentClass->PropertyLink; Property; Property = Property->PropertyLinkNext) { //类属性的名字 FString PropertyName = Property->GetName(); //类属性的类型 FString PropertyType = Property->GetCPPType(); if(PropertyType == "FString") { FStrProperty* StringProperty = CastField<FStrProperty>(Property); void* Addr = StringProperty->ContainerPtrToValuePtr<void>(Student);//这里是获得具体类的对象,才能获得属性的值 FString PropertyValue = StringProperty->GetPropertyValue(Addr); //获取属性元数据 FString CategoryName = StringProperty->GetMetaData(TEXT("Category")); UE_LOG(LogTemp, Warning, TEXT("Student's properties has %s, Type is %s, Value is %s, Meta has %s"), *PropertyName, *PropertyType, *PropertyValue, *CategoryName); //获得类属性变量后,动态修改属性值 StringProperty->SetPropertyValue(Addr, "SettingValue"); FString PropertyValueAfterSetting = StringProperty->GetPropertyValue(Addr); UE_LOG(LogTemp, Warning, TEXT("Student's properties has %s, Type is %s, Value is %s"), *PropertyName, *PropertyType, *PropertyValueAfterSetting); } }

获得类的方法#

Copy
//通过反射获得类的函数 for(TFieldIterator<UFunction> IteratorOfFunction(StudentClass); IteratorOfFunction; ++IteratorOfFunction) { //获取方法名称 UFunction* Function = *IteratorOfFunction; FString FunctionName = Function->GetName(); UE_LOG(LogTemp, Warning, TEXT("Student's function is %s"), *FunctionName); //获取方法标记 EFunctionFlags FunctionFlags = Function->FunctionFlags; UE_LOG(LogTemp, Warning, TEXT("Student's functionFlag is %x"), FunctionFlags); //获得函数的参数以及标志位flag for(TFieldIterator<FProperty> IteratorOfParam(Function); IteratorOfParam; ++IteratorOfParam) { FProperty* Param = *IteratorOfParam; FString ParamName = Param->GetName(); FString ParamType = Param->GetCPPType(); EPropertyFlags ParamFlags = Param->GetPropertyFlags(); UE_LOG(LogTemp, Warning, TEXT("Student's function has %s, ParamType is %s, ParamName is %s, ParamFlag is %x"), *FunctionName, *ParamType, *ParamName, ParamFlags); } }

获取类的父类#

Copy
//通过子类获得父类 ->GetSuperClass() UMiddleStudent* MiddleStudent = NewObject<UMiddleStudent>(); UClass* ParentClass = MiddleStudent->GetClass()->GetSuperClass(); FString ParentName = ParentClass->GetName(); UE_LOG(LogTemp, Warning, TEXT("MiddleStudent's Superclassname is %s"), *ParentName);

判断类的从属关系#

Copy
//判断类的从属关系 Class1->IsChildOf(Class2) UClass* Class1 = UMiddleStudent::StaticClass(); UClass* Class2 = UStudent::StaticClass(); UClass* Class3 = AActor::StaticClass(); if(Class1->IsChildOf(Class2)) { UE_LOG(LogTemp, Warning, TEXT("Class1 is Class2's child")); }else { UE_LOG(LogTemp, Warning, TEXT("Class1 is not Class2's child")); } if(Class3->IsChildOf(Class2)) { UE_LOG(LogTemp, Warning, TEXT("Class3 is Class2's child")); }else { UE_LOG(LogTemp, Warning, TEXT("Class1 is not Class2's child")); }

查找类继承的子类#

Copy
//查找特定类的子类 GetDerivedClasses TArray<UClass*> ClassResults; GetDerivedClasses(UStudent::StaticClass(), ClassResults, false); //UE_LOG(LogTemp, Warning, TEXT("Object's child Count has %d"), ClassResults.Num()); for(int32 Index = 0; Index < ClassResults.Num(); ++Index) { UClass* ClassResult = ClassResults[Index]; FString ClassResultName = ClassResult->GetName(); UE_LOG(LogTemp, Warning, TEXT("UStudent::StaticClass's child has %s"), *ClassResultName); }

查找类生成的对象#

Copy
UGoodMiddleStudent* GMS = NewObject<UGoodMiddleStudent>(this, FName("GMS1")); //查找特定类生成的对象 GetObjectsOfClass TArray<UObject*> ObjectResults; GetObjectsOfClass(UGoodMiddleStudent::StaticClass(), ObjectResults, false); for(UObject* ObjectResult : ObjectResults) { UE_LOG(LogTemp, Warning, TEXT("UGoodMiddleStudent::StaticClass's Object has %s"), *ObjectResult->GetName()); }

根据字符串查找类#

Copy
//根据字符串查找相应的类 UClass* FinderClass = FindObject<UClass>(ANY_PACKAGE, *FString("MiddleStudent"), true); if(FinderClass) { UE_LOG(LogTemp, Warning, TEXT("Class with name:UMiddleStudent has finded")); }

根据字符串查找枚举#

Copy
//根据字符串查找相应的枚举 UEnum* FinderEnum = FindObject<UEnum>(ANY_PACKAGE, *FString("EnumName"), true); if(FinderEnum) { UE_LOG(LogTemp, Warning, TEXT("Enum with name:EnumName has finded")); //遍历枚举项名称 for(int32 Index = 0; Index < FinderEnum->NumEnums(); ++Index) { FString FindedEnumItemName = FinderEnum->GetNameStringByIndex(Index); UE_LOG(LogTemp, Warning, TEXT("EnumName's Property has %s"), *FindedEnumItemName); } }

根据字符串查找类方法#

Copy
//根据名称查找类方法 UE_LOG(LogTemp, Log, TEXT("-----------------------------------------------")); UFunction* Func1 = StudentClass->FindFunctionByName("Study", EIncludeSuperFlag::ExcludeSuper); FString FunctionName = Func1->GetName(); UE_LOG(LogTemp, Warning, TEXT("类方法为:%s"), *FunctionName);

根据字符串查找蓝图类#

这里找到通过字符串找到蓝图类后,通过这个变量获取到蓝图实例类----------->static_cast<UClass*>(WidgetBP->GeneratedClass)

Copy
//通过名称查找蓝图类 UE_LOG(LogTemp, Log, TEXT("-----------------------------------------------")); UBlueprint* FinderBlueprint = FindObject<UBlueprint>(ANY_PACKAGE, *FString("BP_BlueprintClass")); if(FinderBlueprint) { UE_LOG(LogTemp, Warning, TEXT("Blueprint has finded, EnumName is %s"), *FinderBlueprint->GetName()); //判断该类是蓝图类,还是Native类(Native就是C++类的意思) if(FinderBlueprint->IsNative()) { UE_LOG(LogTemp, Warning, TEXT("Blueprint is NativeClass")); }else { UE_LOG(LogTemp, Warning, TEXT("Blueprint is BlueprintClass")); } //蓝图里面类设置的Native选上的意思是打包的时候转为C++类 }

获取所有的类#

Copy
//遍历所有类 UE_LOG(LogTemp, Log, TEXT("-----------------------------------------------")); FString AllClassName = ""; int32 Count = 0; for(TObjectIterator<UClass> ClassIt; ClassIt; ++ClassIt) { ++Count; AllClassName += ClassIt->GetName() + " "; } UE_LOG(LogTemp, Warning, TEXT("虚幻中,总共有%d个类"), Count); //UE_LOG(LogTemp, Warning, TEXT("%s"), *AllClassName); //LogTemp: Warning: 虚幻中,总共有4410个类

使用ProcessEvent调用类方法#

Copy
//使用ProcessEvent调用类方法 //1、给所有方法参数分配空间并初始为0 uint8* AllFunctionParam = static_cast<uint8*>(FMemory_Alloca(Func1->ParmsSize)); FMemory::Memzero(AllFunctionParam, Func1->ParmsSize); //2、给所有方法参数赋值 for(TFieldIterator<FProperty> IteratorOfFuncParm(Func1); IteratorOfFuncParm; ++IteratorOfFuncParm) { FProperty* FunctionParam = *IteratorOfFuncParm; FString FuncParName = FunctionParam->GetName(); if(FuncParName == "InWhat") { *FunctionParam->ContainerPtrToValuePtr<FString>(AllFunctionParam) = "Ball"; } if(FuncParName == "Zhengxing") { *FunctionParam->ContainerPtrToValuePtr<int>(AllFunctionParam) = 5; } } //3、调用方法 StudentClass->ProcessEvent(Func1, AllFunctionParam); //4、打印返回值 UE_LOG(LogTemp, Warning, TEXT("函数返回值为:%d"), *(AllFunctionParam + Func1->ReturnValueOffset));

使用Function.invoke()调用类方法#

Copy
//使用Function.invoke()调用类函数 UE_LOG(LogTemp, Log, TEXT("-----------------------------------------------")); UFunction* Func2 = StudentClass->FindFunctionByName("Function1", EIncludeSuperFlag::ExcludeSuper); uint8* AllFunctionParam1 = static_cast<uint8*>(FMemory_Alloca(Func2->ParmsSize)); FMemory::Memzero(AllFunctionParam1, Func2->ParmsSize); //2、创建FFrame FFrame Frame(nullptr, Func2, &AllFunctionParam1); //3、Invoke调用函数 Func2->Invoke(Student, Frame, AllFunctionParam1); //4、获取返回值 UE_LOG(LogTemp, Warning, TEXT("函数返回值为:%d"), *(AllFunctionParam1 + Func2->ReturnValueOffset));
posted @   hellogiao1  阅读(2053)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示
目录