// 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);
	}

	
}

  

posted on 2025-05-16 18:00  baihuntun  阅读(14)  评论(0)    收藏  举报