26. UE5 RPG同步面板属性(二)

在上一篇,我们解析了UI属性面板的实现步骤:

  1. 首先我们需要通过c++去实现创建GameplayTag,这样可以在c++和UE里同时获取到Tag
  2. 创建一个DataAsset类,用于设置tag对应的属性和显示内容
  3. 创建AttributeMenuWidgetController实现对应逻辑

并且我们实现了第一步,就是在C++里可以创建GameplayTag,并且可以通过单例去获取到Tag的变量。后面属性修改委托也会通过Tag去匹配,这一篇,我们将实现创建一个DataAsset类,用于存储UI显示所需的数据。

创建DataAsset类

这里就有一个问题了,为什么这里使用DataAsset而不是DataTable?

DataTable主要用于存储和读取数据,是一种灵活的数据结构,可以用于存储和维护大量的静态数据。而DataAsset则是一种将资源集合在一起的方式,用于实现资源管理。通过DataAsset,可以将某个对象(如英雄)所使用的所有资源集合在一起,当需要加载该对象时,只需加载对应的DataAsset,从而避免了加载不必要的资源。DataAsset需要手动定义数据结构并添加引用的数据,它只存储引用,并不同步加载所有数据,这使得DataAsset在资源管理方面具有较高的灵活性。

我们需要通过代码去修改DataAsset内的属性显示的实际的值, 这里使用DataAsset更合理。

首先我们创建一个类,类继承于DataAsset

编辑器打开文件,首先,我们先创建一个DataAsset使用的结构体,在结构体中增加三项不会在项目运行中修改的内容,实际的属性数值,我们则需要实时修改,所以,不需要通过蓝图面板设置。EditDefaultsOnly标示代表此属性可以通过面板修改内容。

cpp 复制代码
USTRUCT(BlueprintType)
struct FAttributeInfo
{
	GENERATED_BODY()

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FGameplayTag AttributeTag = FGameplayTag();

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FText AttributeName = FText();

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	FText AttributeDescription = FText();

	UPROPERTY(BlueprintReadOnly)
	float AttributeValue = 0.f;
};

创建完成结构体后,我们添加一个变量AttributeInformation这是一个数组,后面我们将在UE里面可以使用编辑面板添加数据。接着我们又增加了一个函数,FindAttributeInfoForTag可以实现通过Tag进行获取结构体数据,我们将在C++里对数据进行修改,并在UI里对数据进行获取。

cpp 复制代码
UCLASS()
class AURA_API UAttributeInfo : public UDataAsset
{
	GENERATED_BODY()

public:

	FAttributeInfo FindAttributeInfoForTag(const FGameplayTag& AttributeTag, bool bLogNotFound = false) const;

	UPROPERTY(EditDefaultsOnly, BlueprintReadOnly)
	TArray<FAttributeInfo> AttributeInformation;
};

在函数实现那这里,我们通过标签的匹配来获取结构体,如果设置bLogNotFound为true,如果没有获取到数据,我们将打印错误。

cpp 复制代码
// 版权归暮志未晚所有。


#include "AbilitySystem/Data/AttributeInfo.h"

FAttributeInfo UAttributeInfo::FindAttributeInfoForTag(const FGameplayTag& AttributeTag, bool bLogNotFound) const
{
	for(const FAttributeInfo& Info : AttributeInformation)
	{
		//判断标签是否完全匹配
		if(Info.AttributeTag.MatchesTagExact(AttributeTag))
		{
			return Info;
		}
	}

	//未查询到是否打印
	if(bLogNotFound)
	{
		UE_LOG(LogTemp, Error, TEXT("无法从数据列表[%s]中查找到对应的AttributeTag[%s]"), *GetNameSafe(this), *AttributeTag.ToString());
	}

	return FAttributeInfo();
}

这里我们就可以编译打开UE,创建一个数据资产

类选择我们创建的AttributeInfo类

打开之后,只有一个AttributeInformation数组,我们可以根据需要添加子项

我们修改标签,填入显示的名称和描述,将所有的主要属性和次级属性都添加进去。

到这里,我们将属性的DataAsset创建完成,并填充了内容,后续可以通过标签获取然后在UI上面显示出来。

这样,我们的数据有了,第二个步骤也实现了,接下来,我们将创建一个控制器类,从AS内获取数据,并通过委托广播出去,让UI去更新数据显示。

相关推荐
wifi___19 小时前
全局异常处理的原理
java·开发语言
我变成萤火虫20 小时前
河南萌新联赛2026第(四)场:南阳理工学院
数据结构·c++·算法·贪心算法·stl·动态规划
平常心的技术小牛1 天前
Qt-快速上手-QMenuBar
开发语言·qt
赖龙1 天前
pnpm vs npm
前端·npm·node.js
青 春 记 忆1 天前
零基础入门Python11|Git实战:为任务管理器建立版本历史
开发语言·git·vscode·python·python3.11
学如逆水,不进则退1 天前
在线免费音频剪辑:NBTools 可视化波形裁剪 MP3/WAV,本地处理免上传
前端·音视频
Mh1 天前
虚拟滚动真的比普通滚动性能更好吗?
前端·javascript·性能优化
pe7er1 天前
React + Ant Design 中的 IME (输入法合成)安全输入组件
前端
余额瞒着我当琳1 天前
C++--深拷贝三件套 + swap + 写时拷贝 + vector 扩容 + reserve
java·开发语言·c++
Super 含1 天前
Android 启动优化(二):TTID、TTFD 与 Macrobenchmark 启动性能测量
前端