// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "Student.generated.h"
UENUM()
enum class ESubject : uint8
{
Chinese,
Math,
English
};
/**
*
*/
UCLASS(Blueprintable)
class AURAPROJECT_API UStudent : public UObject
{
GENERATED_BODY()
public:
UPROPERTY(VisibleAnywhere, Category="StudentName")
FString Name = "ZhangSan";
UFUNCTION(BlueprintCallable)
void Study()
{
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
FString::Printf(TEXT("Student Study")),
false);
}
UFUNCTION()
int32 Learn(FString BookName)
{
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
FString::Printf(TEXT("Student Learn : %s"), *BookName),
false);
return 0;
}
};
UFUNCTION(BlueprintCallable)
void MyTest();
void MyTest()
{
//获取类名称
UStudent* student = NewObject<UStudent>();
UClass* StudentClass = student->GetClass();
//UClass* StudentClass2 = UStudent::StaticClass();
EClassFlags StudentClassFlags = StudentClass->ClassFlags;
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
FString::Printf(TEXT("ClassName : %s EClassFlags : %x"), *StudentClass->GetName(), StudentClassFlags),
false);
// GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
// FString::Printf(TEXT("ClassName : %s"), *StudentClass2->GetName()));
//获取类属性
for (FProperty* Property = StudentClass->PropertyLink; Property; Property = Property->PropertyLinkNext)
{
FString PropertyName = Property->GetName();
FString PropertyType = Property->GetCPPType();
if (PropertyType == "FString")
{
FStrProperty* StrProperty = CastField<FStrProperty>(Property);
FString Category = StrProperty->GetMetaData(TEXT("Category"));
void* Addr = StrProperty->ContainerPtrToValuePtr<void>(student);
FString PropertyValue = StrProperty->GetPropertyValue(Addr);
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
FString::Printf(TEXT("Category : %s PropertyType : %s PropertyName : %s PropertyValue : %s "), *Category, *PropertyType, *PropertyName, *PropertyValue),
false);
StrProperty->SetPropertyValue(Addr, "LiSi");
FString PropertyValueChanged = StrProperty->GetPropertyValue(Addr);
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
FString::Printf(TEXT("PropertyType : %s PropertyName : %s PropertyValue : %s "), *PropertyType, *PropertyName, *PropertyValueChanged),
false);
}
}
//获取类方法
for (TFieldIterator<UFunction> IteratorOfFunction(StudentClass); IteratorOfFunction; ++IteratorOfFunction)
{
UFunction* Function = *IteratorOfFunction;
EFunctionFlags Flags = Function->FunctionFlags;
FString FunctionName = Function->GetName();
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
FString::Printf(TEXT("FunctionFlags : %x FunctionName : %s"), Flags, *FunctionName),
false);
for (TFieldIterator<FProperty> IteratorOfProperty(Function); IteratorOfProperty; ++IteratorOfProperty)
{
FProperty* Property = *IteratorOfProperty;
FString PropertyName = Property->GetName();
FString PropertyType = Property->GetCPPType();
EPropertyFlags PropertyFlags = Property->GetPropertyFlags();
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
FString::Printf(TEXT("PropertyType : %s PropertyName : %s PropertyFlags : %x"), *PropertyType, *PropertyName, PropertyFlags),
false);
}
}
//获取超类名称
FString SuperClassName = StudentClass->GetSuperClass()->GetName();
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
FString::Printf(TEXT("Student SuperClassName : %s"), *SuperClassName),
false);
//判断一个类是否为另一个类的子类
FString StudentIsObjectChildClass = UStudent::StaticClass()->IsChildOf(UObject::StaticClass()) ? "True" : "False";
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
FString::Printf(TEXT("Student Is Object ChildClass : %s"), *StudentIsObjectChildClass),
false);
//查找指定类的所有子类
TArray<UClass*> Results;
GetDerivedClasses(UStudent::StaticClass(), Results, false); //false 不寻找子类的子类
for (int i=0; i < Results.Num(); i++)
{
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
FString::Printf(TEXT("Student DerivedClasses Has : %s"), *Results[i]->GetName()),
false);
}
//查找指定类生成的所有对象
TArray<UObject*> ObjectResults;
GetObjectsOfClass(UStudent::StaticClass(), ObjectResults, false);
for (int i=0; i < ObjectResults.Num(); i++)
{
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
FString::Printf(TEXT("Student Instance Has : %s"), *ObjectResults[i]->GetName()),
false);
}
//根据字符串查找类
UClass* FoundClass = FindObject<UClass>(ANY_PACKAGE, *FString("Student"), true);
if (FoundClass)
{
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
FString::Printf(TEXT("Found Student Class By String : %s"), *FoundClass->GetName()),
false);
}
//根据字符串查找枚举
UEnum* FoundEnum = FindObject<UEnum>(ANY_PACKAGE, *FString("ESubject"), true);
if (FoundEnum)
{
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
FString::Printf(TEXT("Found ESubject Enum By String : %s"), *FoundEnum->GetName()),
false);
for (int i = 0; i < FoundEnum->NumEnums(); i++)
{
FString ItemName = FoundEnum->GetNameStringByIndex(i);
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
FString::Printf(TEXT("ESubject Enum Item Has : %s"), *ItemName),
false);
}
}
//根据字符串查找蓝图类
UBlueprint* FoundBlueprint = FindObject<UBlueprint>(ANY_PACKAGE, *FString("BP_Student"), true);
if (FoundBlueprint)
{
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
FString::Printf(TEXT("Found BP_Student By String : %s"), *FoundBlueprint->GetName()),
false);
FString IsNative = FoundBlueprint->IsNative() ? "True" : "False";
GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
FString::Printf(TEXT("BP_Student IsNative : %s"), *IsNative),
false);
}
//遍历所有类
// for (TObjectIterator<UClass> ClassIterator; ClassIterator; ++ClassIterator)
// {
// GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
// FString::Printf(TEXT("ClassName : %s"), *ClassIterator->GetName()),
// false);
// }
//根据名称查找类方法
UFunction* LearnFunc = StudentClass->FindFunctionByName(FName("Learn"), EIncludeSuperFlag::ExcludeSuper);
if (LearnFunc)
{
// GEngine->AddOnScreenDebugMessage(-1, 100.f, FColor::Cyan,
// FString::Printf(TEXT("StudyFunc : %s"), *StudyFunc->GetName()),
// false);
//通过反射调用方法
//给方法所有参数分配空间 并初始化为0
uint8* AllFunctionParamSize = static_cast<uint8*>(FMemory_Alloca(LearnFunc->ParmsSize));
FMemory::Memzero(AllFunctionParamSize, LearnFunc->ParmsSize);
//给方法所有参数赋值
for (TFieldIterator<FProperty> IteratorOfProperty(LearnFunc); IteratorOfProperty; ++IteratorOfProperty)
{
FProperty* FunctionParam = *IteratorOfProperty;
FString FunctionParamType = FunctionParam->GetCPPType();
if (FunctionParamType == "FString")
{
*FunctionParam->ContainerPtrToValuePtr<FString>(AllFunctionParamSize) = FString("Math");
}
}
//调用方法
UObject* Obj = Cast<UObject>(student);
Obj->ProcessEvent(LearnFunc, AllFunctionParamSize);
}
//UFunction Invoke
UFunction* StudyFunc = StudentClass->FindFunctionByName(FName("Study"), EIncludeSuperFlag::ExcludeSuper);
if (StudyFunc)
{
uint8* AllFunctionParamSize = static_cast<uint8*>(FMemory_Alloca(LearnFunc->ParmsSize));
FMemory::Memzero(AllFunctionParamSize, LearnFunc->ParmsSize);
FFrame Frame(nullptr, StudyFunc, &AllFunctionParamSize);
StudyFunc->Invoke(student, Frame, &AllFunctionParamSize + StudyFunc->ReturnValueOffset);
//获取返回值
//int* ReturnValue = (int*)(&AllFunctionParamSize + StudyFunc->ReturnValueOffset);
}
}