动态属性系统

avatar`
Yuewu(罗传月武)
Updated: Jun 28, 2025

介绍

灵感来自于Lyra的GampelayTagStack,是通过GameplayTag->Integer来追踪管理动态数值的一种机制。在GIS中,进一步扩大了这个概念,并将其称为Tag属性容器。

Tag属性容器

GIS封装了三种方式以实现动态属性系统,分别是:

  • GameplayTagIntegerContainer:包含一个GameplayTagInteger列表,每一项表示一个Tag到Int32的键值对。
  • GameplayTagBoolContainer:包含一个GameplayTagBool列表,每一项表示一个Tag到bool的键值对。
  • GameplayTagFloatContianer:包含一个GameplayTagFloat列表,每一项表示一个Tag到float的键值对。

它们均由FastArraySerializer实现,提供高效的网络复制,和简化的数据变化通知回调,Container中的每一项,也都标记了SaveGame,便于在单机游戏,或者服务端进行数据序列化。

使用属性容器步骤

以货币系统为例,添加FloatContainer到你的类中。

1 UPROPERTY(VisibleAnywhere, BlueprintReadOnly, SaveGame, Replicated, meta=(Categories="GIS.Currency"))
2 FGIS_GameplayTagFloatContainer CurrencyContainer;

在构造函数中,将当前类设置到容器的ContainerOwner

1UGIS_CurrencySystemComponent::UGIS_CurrencySystemComponent()
2{
3 PrimaryComponentTick.bCanEverTick = false;
4 SetIsReplicatedByDefault(true);
5 bReplicateUsingRegisteredSubObjectList = true;
6 bWantsInitializeComponent = true;
7 CurrencyContainer.ContainerOwner = this;
8}

确保该字段正确网络同步,同步条件可以根据项目需求自定义。

1void UGIS_CurrencySystemComponent::GetLifetimeReplicatedProps(TArray<class FLifetimeProperty>& OutLifetimeProps) const
2{
3 Super::GetLifetimeReplicatedProps(OutLifetimeProps);
4
5 DOREPLIFETIME(ThisClass, CurrencyContainer);
6}

确保你的Class同时实现了IGIS_GameplayTagFloatContainerOwner接口

1UCLASS(ClassGroup=(GIS), BlueprintType, Blueprintable, meta=(BlueprintSpawnableComponent))
2class GENERICINVENTORYSYSTEM_API UGIS_CurrencySystemComponent : public UActorComponent, public IGIS_GameplayTagFloatContainerOwner

然后实现接口中的OnTagFloatUpdate,该接口允许你针对属性变化做出反应。

1void UGIS_CurrencySystemComponent::OnTagFloatUpdate(const FGameplayTag& Tag, float OldValue, float NewValue)
2{
3 OnCurrencyChangedEvent.Broadcast(Tag, OldValue, NewValue);
4}

OnTagFloatUpdate会在任意属性变更时调用,包括服务端和客户端。

应用案例

此特性是为了让动态属性变得更容易实现,代码是可复用的。

道具实例和货币系统都用到了动态属性。当然,你也可以将其应用到其他系统中,而不仅仅只是库存系统。

logo_small
罗传月武

© 罗传月武 @2025 版权所有.