摘要:本文介绍了虚幻引擎GameplayAbilitySystem(GAS)框架中技能系统的实现方法。主要内容包括如何创建GameplayAbility子类GA_Combo,重写ActivateAbility函数实现技能激活逻辑,使用CommitAbility检查资源条件,以及通过EndAbility处理技能结束。同时说明了如何在AbilitySystemComponent中添加技能数组,并使用GiveAbility方法授予角色初始能力。最后指出这些操作应在服务器端实施,并提供了角色类中的调用示例。
Gameplay Ability
1.创建类:
基于CGameplayAbility创建子类:GA_Combo
2.在GA_Combo类里重写函数:
Source/Crunch/Public/GAS/GameplayAbility/GA_Combo.h:
public:
virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData) override;
这是一个虚幻引擎Gameplay Ability System (GAS)框架中用于激活技能的核心虚函数重写声明。该函数在技能被激活时调用,主要功能包括:
函数参数说明:
-
Handle:技能规格的唯一标识符
-
ActorInfo:包含施法者相关信息的结构体
-
ActivationInfo:技能激活相关信息
-
TriggerEventData:触发技能的事件数据
典型实现流程:
-
首先调用CommitAbility检查资源/冷却条件
-
执行技能核心逻辑(如应用GameplayEffect、播放动画等)
-
最后调用EndAbility结束技能
注意事项:
-
需要先检查CommitAbility返回值
-
必须调用EndAbility来正确结束技能
-
可以在派生类中扩展特定功能(如被动技能处理)
相关扩展:
-
被动技能通常需要重写此函数并绑定结束回调监听
-
交互系统(如Lyra)会在此函数中处理交互逻辑
-
可通过GameplayTag配置输入激活方式
(1)检查两件事: 技能是否冷却中 \ 法力是否足够
virtual bool CommitAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, OUT FGameplayTagContainer* OptionalRelevantTags = nullptr);
这是虚幻引擎GAS框架中用于提交技能资源/冷却的核心函数声明。该函数通常在技能激活前调用,用于检查并消耗技能所需的资源条件。
主要功能特点:
-
返回值:返回bool类型,表示资源/冷却条件是否满足
- true:条件满足,可以激活技能
- false:条件不满足,应取消技能激活
-
典型使用场景:
- 在
ActivateAbility
函数中首先调用该函数进行条件检查 - 失败时应调用
CancelAbility
终止技能 - 成功后可继续执行技能逻辑
- 在
-
参数说明:
Handle
:技能规格的唯一标识符ActorInfo
:包含施法者信息的结构体ActivationInfo
:技能激活相关信息OptionalRelevantTags
:输出参数,可返回相关GameplayTag
-
实现建议:
- 通常与
ActivateAbility
和EndAbility
配合使用形成完整生命周期 - 派生类可重写该函数实现自定义资源检查逻辑
- 被动技能可能需要特殊处理该函数的调用时机
- 通常与
if (!CommitAbility(Handle, ActorInfo, ActivationInfo))
{
EndAbility(Handle, ActorInfo, ActivationInfo, true, false);
return;
}
(2)条件不满足,取消技能施法
/** Native function, called if an ability ends normally or abnormally. If bReplicate is set to true, try to replicate the ending to the client/server */
virtual void EndAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled);
这是虚幻引擎GAS系统中处理技能结束的核心虚函数声明,主要功能包括:
参数说明:
Handle
:标识技能实例的唯一句柄ActorInfo
:包含施法者相关信息的结构体ActivationInfo
:记录技能激活状态的数据bReplicateEndAbility
:控制是否同步结束状态到网络客户端/服务端bWasCancelled
:标识技能是被取消还是正常结束
典型实现要点:
- 必须调用父类的
EndAbility
确保基础清理逻辑执行 - 被动技能通常需要在此函数中解除事件绑定
- 自动移除技能时可配合
OnGiveAbility
实现完整生命周期管理
派生类扩展建议:
- 可结合
EWarriorAbilityActivationPolicy
枚举实现不同的结束策略 - 通过
bWasCancelled
参数区分正常结束和强制取消的情况 - 网络同步时需正确处理
bReplicateEndAbility
参数
(3)条件满足时,触发事件或者打印:
void UGA_Combo::ActivateAbility(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo,
const FGameplayAbilityActivationInfo ActivationInfo, const FGameplayEventData* TriggerEventData)
{
Super::ActivateAbility(Handle, ActorInfo, ActivationInfo, TriggerEventData);
if (!CommitAbility(Handle, ActorInfo, ActivationInfo))
{
EndAbility(Handle, ActorInfo, ActivationInfo, true, false);
return;
}
UE_LOG(LogTemp, Warning, TEXT("UGA_Combo::ActivateAbility"));
}
但是,释放技能前,要先将技能附加给玩家:
(4)在GAS中,添加技能数组:
Source/Crunch/Public/GAS/CAbilitySystemComponent.h:
UPROPERTY(EditDefaultsOnly, Category="Gameplay Abilities")
TArray<TSubclassOf<UCGameplayAbility>> Abilities;
UPROPERTY(EditDefaultsOnly, Category="Gameplay Abilities")
TArray<TSubclassOf<UCGameplayAbility>> BasicAbilities;
上述代码错误,应该是:
UPROPERTY(EditDefaultsOnly, Category="Gameplay Abilities")
TArray<TSubclassOf<UGameplayAbility>> Abilities; //激活后的能力
UPROPERTY(EditDefaultsOnly, Category="Gameplay Abilities")
TArray<TSubclassOf<UGameplayAbility>> BasicAbilities; //初始能力
(5)授予能力
//授予初始能力
void GiveInitialAbilities();
Source/Crunch/Private/GAS/CAbilitySystemComponent.cpp:
void UCAbilitySystemComponent::GiveInitialAbilities()
{
if (!GetOwner() || !GetOwner()->HasAuthority()) return;
for (const TSubclassOf<UGameplayAbility>& AbilityClass : Abilities)
{
FGameplayAbilitySpec GameplayAbilitySpec = FGameplayAbilitySpec(AbilityClass, 0, INDEX_NONE, nullptr);
GiveAbility(GameplayAbilitySpec);
}
for (const TSubclassOf<UGameplayAbility>& AbilityClass : BasicAbilities)
{
FGameplayAbilitySpec GameplayAbilitySpec = FGameplayAbilitySpec(AbilityClass, 1, INDEX_NONE, nullptr);
GiveAbility(GameplayAbilitySpec);
}
}
其中:
/** Version that takes an ability class */
FGameplayAbilitySpec(TSubclassOf<UGameplayAbility> InAbilityClass, int32 InLevel = 1, int32 InInputID = INDEX_NONE, UObject* InSourceObject = nullptr);
这是虚幻引擎GAS系统中FGameplayAbilitySpec
结构体的构造函数重载版本,专门用于通过技能类模板参数初始化技能规格。该构造函数主要处理以下参数:
核心参数说明:
InAbilityClass
:必须继承自UGameplayAbility
的模板类,用于指定技能类型InLevel
:默认值为1的技能等级参数InInputID
:绑定输入操作的ID,默认INDEX_NONE
表示不绑定输入InSourceObject
:技能来源对象指针,默认nullptr
典型使用场景:
- 在
GiveAbility
调用时构造技能规格实例 - 通过
TSubclassOf
模板确保类型安全 - 与
UGameplayAbilitySystemComponent::GiveAbility
配合实现技能授予
注意事项:
- 派生类需确保
TSubclassOf<T>
中的T与UGameplayAbility
存在继承关系 - 输入ID需与项目的输入映射系统匹配
- 源对象通常用于标识技能来源(如装备、Buff等)
FGameplayAbilitySpecHandle GiveAbility(const FGameplayAbilitySpec& AbilitySpec);
这是虚幻引擎GAS系统中UAbilitySystemComponent
类的核心方法,用于向Actor授予游戏技能。该方法的主要功能特点如下:
参数说明:
AbilitySpec
:包含技能类引用、输入绑定、等级等配置信息的结构体- 返回值
FGameplayAbilitySpecHandle
:用于后续管理该技能的唯一句柄
执行流程:
- 仅在服务端有效执行,客户端调用会被忽略
- 内部会创建技能实例并初始化状态数据
- 自动处理网络同步和预测相关逻辑
注意事项:
- 需确保
AbilitySpec
中的技能类已正确继承UGameplayAbility
- 通过返回的Handle可后续进行技能取消或移除操作
- 被动技能通常需要设置
InstancingPolicy
为InstancedPerActor
(6)我们在哪里使用它们呢?
答案:服务器端
Source/Crunch/Private/Character/CCharacter.cpp:
void ACCharacter::ServerSideInit()
{
CAbilitySystemComponent->InitAbilityActorInfo(this, this); //应用能力系统组件前都要初始化
CAbilitySystemComponent->ApplyInitialEffects(); //效果初始化
CAbilitySystemComponent->GiveInitialAbilities(); //能力初始化
}
3.在角色蓝图里,添加GA_Combo