虚幻引擎5 GAS开发俯视角RPG游戏 P02-10 生命值与魔法值

Attributes 是由 FGameplayAttributeData定义的浮点值。 Attributes能够表达从角色的生命值到角色等级到药瓶的价格等任何数值。 如果Actor拥有游戏性相关的数值,那么可以考虑使用Attribute。Attributes 通常只能被GameplayEffects 修改,因此ASC可以 预测 这个修改。

定义AttributeSet属性

在之前的文章中,我创建了AS的文件,里面没有添加角色属性。
这里我先创建了两个属性,一个是Health,用来表示角色的当前血量,另一个是MaxHealth,代表角色的最大血量。

1.创建FGameplayAttributeData类型的变量Health

	UPROPERTY(BlueprintReadOnly, Category="Vital Attributes")
	FGameplayAttributeData Health;

这段代码定义了UE5 GAS系统中一个基础的生命值属性(Health),主要包含以下特性:

属性类型‌:

  • 使用FGameplayAttributeData存储属性数据,包含BaseValue和CurrentValue两个浮点值
  • 基础值(BaseValue)表示永久属性值,当前值(CurrentValue)包含临时修改效果

元数据配置‌:

  • BlueprintReadOnly使属性在蓝图中可见但不可修改
  • Category="Vital Attributes"在编辑器中将属性归类到"Vital Attributes"组

扩展功能‌:

  • 通常需要配合ATTRIBUTE_ACCESSORS宏生成Get/Set方法
  • 建议添加ReplicatedUsing实现网络同步和回调处理
  • 可通过PreAttributeChange进行数值范围限制

这是GAS系统中最基础的属性定义方式,适用于角色生命值、法力值等核心游戏属性。完整的实现还应包含对应的MaxHealth属性和网络同步逻辑。

2.要想属性被复制,首先在属性集标头的属性定义中加入ReplicatedUsingSpecifier,这将设置一个回调函数,有助于在远程系统上进行预测。

UPROPERTY(BlueprintReadOnly, Category="Vital Attributes", ReplicatedUsing = OnRep_Health)
	FGameplayAttributeData Health;
	ATTRIBUTE_ACCESSORS(UCCAttributeSet, Health);
	
	UPROPERTY(BlueprintReadOnly, Category="Vital Attributes", ReplicatedUsing = OnRep_MaxHealth)
	FGameplayAttributeData MaxHealth;
	ATTRIBUTE_ACCESSORS(UCCAttributeSet, MaxHealth);

这段代码展示了UE5 GAS(游戏能力系统)中生命值属性的标准实现方式,主要包含以下关键点:

属性定义‌:

  • 定义了Health(当前生命值)和MaxHealth(最大生命值)两个核心属性
  • 使用FGameplayAttributeData类型存储属性数据,包含BaseValue和CurrentValue

元数据配置‌:

  • BlueprintReadOnly:使属性在蓝图中可见但不可直接修改
  • Category="Vital Attributes":在编辑器中将属性归类到"Vital Attributes"组
  • ReplicatedUsing:指定属性网络同步时的回调函数(OnRep_Health/OnRep_MaxHealth)

访问器生成‌:

  • 使用ATTRIBUTE_ACCESSORS宏自动生成属性的Get/Set/Init方法
  • 宏参数指定了属性所属类(UCCAttributeSet)和属性名(Health/MaxHealth)

网络同步‌:

  • 需要配合实现GetLifetimeReplicatedProps函数注册复制属性
  • 需要定义对应的OnRep_HealthOnRep_MaxHealth回调函数处理客户端更新

这是GAS系统中属性定义的推荐模式,确保了属性在单机和网络环境下的正确行为。

3.声明复制回调函数:

	void OnRep_Health(FGameplayAttributeData& OldHealth);

这时,上面的红线还在,提示找不到回调函数,所以,必须加上:UFUNCTION()

这段代码定义了UE5 GAS系统中生命值属性的网络复制回调函数,主要功能如下:

函数声明‌:

  • 使用UFUNCTION()宏标记为反射函数,支持蓝图调用和网络通信
  • 参数OldHealth保存属性变化前的旧值,用于差值比较

实现要点‌:

  • 通常在.cpp文件中使用GAMEPLAYATTRIBUTE_REPNOTIFY宏实现具体逻辑
  • 该宏会自动处理属性变化的网络同步和预测补偿

配套实现‌:

  • 需要配合GetLifetimeReplicatedProps注册复制属性
  • 建议在.cpp中添加如下实现:
void UCCAttributeSet::OnRep_Health(const FGameplayAttributeData& OldHealth) const
{
    GAMEPLAYATTRIBUTE_REPNOTIFY(UCCAttributeSet, Health, OldHealth);
}

系统关联‌:

  • 当Health属性在服务端变化时自动触发客户端回调
  • 常用于更新UI或触发视觉效果

4.在属性集的源文件中,定义你复制的回调函数。函数的主体可以用游戏玩法技能系统定义的一个宏来表示。

// 使用默认的游戏玩法属性系统更新通知行为。
         GAMEPLAYATTRIBUTE_REPNOTIFY(UCCAttributeSet, Health, OldHealth);

所以在CCAttributeSet.cpp文件里,定义方法:

#include "AbilitySystemComponent.h"

void UCCAttributeSet::OnRep_Health(const FGameplayAttributeData& OldHealth) const
{
	// 使用默认的游戏玩法属性系统更新通知行为。
	GAMEPLAYATTRIBUTE_REPNOTIFY(UCCAttributeSet, Health, OldHealth);
}

5.如果这是你的属性集中的首个复制的属性,你要对公共的GetLifetimeReplicatedProps函数设置一个覆盖。

	     /** Marks the properties we wish to replicate */
     virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;

这是UE5网络同步系统中的核心函数声明,用于定义属性复制规则。主要功能和使用要点如下:

函数作用‌:

  • 控制Actor/Component属性的网络同步条件和生命周期
  • 通过DOREPLIFETIME宏注册需要同步的属性

实现规范‌:

  • 必须声明为override并调用父类实现
  • 参数名必须严格使用OutLifetimeProps(区分大小写)
  • 需配合ReplicatedReplicatedUsing属性标记使用

典型实现示例‌:

void UYourClass::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
    Super::GetLifetimeReplicatedProps(OutLifetimeProps);
    DOREPLIFETIME(UYourClass, YourReplicatedProperty);
}

同步控制‌:

  • 可使用COND_系列条件限定同步范围(如COND_OwnerOnly
  • 对TArray类型属性建议使用FastArraySerializer优化同步效率
  • 同步操作发生在每帧Tick循环的收尾阶段

6.将游戏玩法属性添加到属性集源文件中的GetLifetimeReplicatedProps函数中,如下所示:

void UCCAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
	// 为生命值添加复制功能。
	DOREPLIFETIME_CONDITION_NOTIFY(UCCAttributeSet, Health, COND_None, REPNOTIFY_Always);
}

这段代码实现了UE5 GAS系统中核心属性的网络同步功能,主要特点如下:

基础结构‌:

  • 继承父类的Super::GetLifetimeReplicatedProps调用确保基础属性同步
  • 使用TArray<FLifetimeProperty>参数管理所有需要同步的属性

同步宏说明‌:

  • DOREPLIFETIME_CONDITION_NOTIFY宏包含四个关键参数:
    • 类名(UCCAttributeSet)
    • 属性名(如Health)
    • 同步条件(COND_None表示无条件同步)
    • 通知策略(REPNOTIFY_Always强制触发RepNotify)

同步属性类型‌:

  • 生命值相关:HealthMaxHealth构成完整的生命值系统
  • 魔法值相关:ManaMaxMana实现魔法资源管理
  • 这种配对设计符合RPG游戏的常见属性架构

实现建议‌:

  • 建议为每个属性添加对应的OnRep_回调函数处理客户端更新
  • 对于频繁变化的属性可考虑COND_SkipOwner优化网络流量
  • 结构体属性需使用DOREPLIFETIME_WITH_PARAMS宏处理嵌套复制

该实现是GAS网络同步的标准模式,确保所有客户端能实时更新角色状态。若需扩展其他属性(如攻击力/防御力),可参照相同模式添加同步条目。

后面再添加最大血量、魔法值、最大魔法值

CCAttributeSet.h:

// 版权归陈超所有

#pragma once

#include "CoreMinimal.h"
#include "AttributeSet.h"
#include "CCAttributeSet.generated.h"

/**
 * 
 */
UCLASS()
class CC_AURA_API UCCAttributeSet : public UAttributeSet
{
	GENERATED_BODY()

public:
	UCCAttributeSet();

	/** 标记我们希望复制的属性
	 * 如果这是你的属性集中的首个复制的属性,你要对公共的GetLifetimeReplicatedProps函数设置一个覆盖。
	 */
	virtual void GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const override;
	
/**************************************************************************************************************/
	//~Begin 属性
	UPROPERTY(BlueprintReadOnly, Category="Vital Attributes", ReplicatedUsing = OnRep_Health)
	FGameplayAttributeData Health;
	
	UPROPERTY(BlueprintReadOnly, Category="Vital Attributes", ReplicatedUsing = OnRep_MaxHealth)
	FGameplayAttributeData MaxHealth;

	UPROPERTY(BlueprintReadOnly, Category="Vital Attributes", ReplicatedUsing = OnRep_Mana)
	FGameplayAttributeData Mana;
	
	UPROPERTY(BlueprintReadOnly, Category="Vital Attributes", ReplicatedUsing = OnRep_MaxMana)
	FGameplayAttributeData MaxMana;

	//~End 属性
/**************************************************************************************************************/
	//~Begin 属性复制回调函数
	UFUNCTION()
	void OnRep_Health(const FGameplayAttributeData& OldHealth) const;

	UFUNCTION()
	void OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth) const;

	UFUNCTION()
	void OnRep_Mana(const FGameplayAttributeData& OldMana) const;

	UFUNCTION()
	void OnRep_MaxMana(const FGameplayAttributeData& OldMaxMana) const;

	//~End 属性复制回调函数
/**************************************************************************************************************/
};

CCAttributeSet.cpp:

// 版权归陈超所有


#include "AbilitySystem/CCAttributeSet.h"

#include "AbilitySystemComponent.h"
#include "Net/UnrealNetwork.h"

UCCAttributeSet::UCCAttributeSet()
{
}

//将游戏玩法属性添加到属性集源文件中的GetLifetimeReplicatedProps函数中
void UCCAttributeSet::GetLifetimeReplicatedProps(TArray<FLifetimeProperty>& OutLifetimeProps) const
{
	Super::GetLifetimeReplicatedProps(OutLifetimeProps);
	
	// 为生命值添加复制功能。
	DOREPLIFETIME_CONDITION_NOTIFY(UCCAttributeSet, Health, COND_None, REPNOTIFY_Always);
	// 为最大生命值添加复制功能。
	DOREPLIFETIME_CONDITION_NOTIFY(UCCAttributeSet, MaxHealth, COND_None, REPNOTIFY_Always);
	// 为魔法值添加复制功能。
	DOREPLIFETIME_CONDITION_NOTIFY(UCCAttributeSet, Mana, COND_None, REPNOTIFY_Always);
	// 为最大魔法值添加复制功能。
	DOREPLIFETIME_CONDITION_NOTIFY(UCCAttributeSet, MaxMana, COND_None, REPNOTIFY_Always);
}



//~Begin 属性复制回调函数
void UCCAttributeSet::OnRep_Health(const FGameplayAttributeData& OldHealth) const
{
	// 使用默认的游戏玩法属性系统更新通知行为。
	GAMEPLAYATTRIBUTE_REPNOTIFY(UCCAttributeSet, Health, OldHealth);
}

void UCCAttributeSet::OnRep_MaxHealth(const FGameplayAttributeData& OldMaxHealth) const
{
	// 使用默认的游戏玩法属性系统更新通知行为。
	GAMEPLAYATTRIBUTE_REPNOTIFY(UCCAttributeSet, MaxHealth, OldMaxHealth);
}

void UCCAttributeSet::OnRep_Mana(const FGameplayAttributeData& OldMana) const
{
	// 使用默认的游戏玩法属性系统更新通知行为。
	GAMEPLAYATTRIBUTE_REPNOTIFY(UCCAttributeSet, Mana, OldMana);
}

void UCCAttributeSet::OnRep_MaxMana(const FGameplayAttributeData& OldMaxMana) const
{
	// 使用默认的游戏玩法属性系统更新通知行为。
	GAMEPLAYATTRIBUTE_REPNOTIFY(UCCAttributeSet, MaxMana, OldMaxMana);
}

//~End 属性复制回调函数

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值