UE5中使用反射系统进行结构体字段值的获取与设置(c++编写、蓝图调用)

一、需求描述:

最近在做一个数字孪生项目,需要大量的接收上游的数据显示到程序界面上,同时程序也会给上游反馈数据,比如一个按钮,按下时,给上游反馈1,松开后反馈0.

二:问题说明

需要展示的数据有很多,差不多400个数据。不仅要接收数据显示,还要反馈给上游数据。由于上游制定的传输协议是UDP,将字段都塞到了一个struct中,这个结构我们不能要求改变成更便捷的,所以,只能基于这个通信结构进行开发优化。传统方式是在c++中写对应字段的Get、Set函数,开放给蓝图,支持蓝图调用。但是因为字段量级太大,同时重复性工作非常多,并且这些字段可能还会随时增加,如果依旧采用传统方式,就会导致每次新增时,都要新增代码。

三、解决方案

基于这种情况,我采用的通过反射系统进行结构体字段值的获取与赋值方式。这样,每次结构体有变化时,只需要修改结构体,其他字段的更新与获取无需任何改变。

整体调用的方式为,c++中编写反射脚本,传入字段名可获取对应字段值与设置对应字段值,在蓝图中可调用该方法,并传入字段名。

c++脚本:

首先新建基于BlueprintFunctionLibrary的脚本,

测试结构体:

注意:如果要使用反射,结构体和字段,必须进行UE的标记。

USTRUCT(BlueprintType)
struct FTestStruct
{
	GENERATED_BODY()
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "TestStruct")
	double aa;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "TestStruct")
	double bb;
	UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "TestStruct")
	int cc;
}

.h文件脚本:

static FTestStruct testStruct;

UFUNCTION(BlueprintCallable, Category = "UDP")
static bool GetStructField(const FString& FieldName, FString& OutValue);

UFUNCTION(BlueprintCallable, Category = "UDP")
static bool SetStructField(const FString& FieldName, const FString& inputvalue);

.cpp脚本:

#include "UObject/NoExportTypes.h"
#include "UObject/Class.h"
#include "UObject/PropertyPortFlags.h"
#include "UObject/TextProperty.h"
#include "UObject/UnrealType.h"


bool UMyUDPBPFunctionLibrary::GetStructField(const FString& FieldName, FString& OutValue)
{
	OutValue = "";


		UStruct* stu = FTestStruct::StaticStruct();



		if (stu)
		{
			// 使用反射系统获取字段属性
			FProperty* Property = stu->FindPropertyByName(*FieldName);
			if (Property)
			{

				// 获取字段的值
				const void* ValuePtr = Property->ContainerPtrToValuePtr<void>(&testStruct);
				if (ValuePtr)
				{
					// 将值转换为字符串并存储在OutValue中
					Property->ExportTextItem(OutValue, ValuePtr, nullptr, nullptr, PPF_None);
					return true;
				}
				//}
			}
		}
		return false;

}


bool UMyUDPBPFunctionLibrary::SetStructField(const FString& FieldName, const FString& inputvalue)
{

		UStruct* stu = FSendToMagic::StaticStruct();
		if (stu)
		{
			// 使用反射系统获取字段属性
			FProperty* Property = stu->FindPropertyByName(*FieldName);
			if (Property)
			{
				void* ValuePtr = Property->ContainerPtrToValuePtr<void>(&SPackage_Magic);
				// 获取字段的值
				//const void* ValuePtr = Property->ContainerPtrToValuePtr<void>(&RPackage_Dymola22);
				if (ValuePtr)
				{
					Property->ImportText(*inputvalue, ValuePtr, 0, nullptr);
					return true;
				}
				
		  }
		
		return false;
	}

在蓝图中,即可全局调用GetStructField节点和SetStructField即可使用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值