1169 字
6 分钟
UE5 Gameplay Ability System (GAS) 完全指南
深入解析Unreal Engines 5的Gameplay Ability System,从核心概念到实战应用,帮你快速掌握技能系统开发
前言
Gameplay Ability System(GAS)是Epic官方推出的强大技能系统框架,被《堡垒之夜》等顶级游戏采用。它提供了一套完整的技能、buff、冷却管理的解决方案。
本文带你从零理解GAS的设计思想,并手把手实现一个简单的技能系统。
什么是GAS?
GAS是Unreal Engine的核心技能/属性系统框架,核心特点是:
| 特性 | 说明 |
|---|---|
| ASC架构 | Ability System Component驱动 |
| 属性委托 | GameplayAttribute系统 |
| 技能标签 | Tag驱动的权限控制 |
| 预测系统 | 客户端预测支持 |
| 技能委托 | 完整的生命周期事件 |
简单来说:GAS让你能优雅地实现技能、buff、属性、冷却一套完整的战斗系统。
GAS核心概念
1. ASC(Ability System Component)
挂在Actor上的核心组件,负责管理所有技能:
UPROPERTY()UAbilitySystemComponent* AbilitySystemComponent;2. AttributeSet(属性集)
存储角色的数值属性(生命值、魔法值、攻击力等):
UCLASS()class UMyAttributeSet : public UAttributeSet{ GENERATED_BODY()
public: UPROPERTY() float Health = 100.f;
UPROPERTY() float MaxHealth = 100.f;
UPROPERTY() float Mana = 50.f;
UPROPERTY() float MaxMana = 50.f;
UPROPERTY() float AttackPower = 10.f;};3. GameplayAbility(技能)
具体的技能逻辑:
UCLASS()class UMyGameplayAbility : public UGameplayAbility{ GENERATED_BODY()
public: // 技能激活时调用 virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo& ActivationInfo, FOnGameplayAbilityEnded::FDelegate* OnEnded) override;
// 技能结束时调用 virtual void EndAbility(const FGameplayAbilitySpecHandle Handle, FGameplayAbilityActorInfo* ActorInfo, FGameplayAbilityActivationInfo ActivationInfo, bool bReplicateEndAbility, bool bWasCancelled) override;};4. GameplayEffect(效果)
用于修改属性(buff/debuff):
// 瞬间生效的效果(回血、掉血)TSubclassOf<UGameplayEffect> InstantEffect;
// 持续效果(持续回血、dot)TSubclassOf<UGameplayEffect> DurationEffect;
// 无限持续效果(buff)TSubclassOf<UGameplayEffect> InfiniteEffect;5. GameplayTags(标签)
用于权限控制和技能识别:
// 在ProjectSettings中定义Tag// Ability.Book.Ice// Buff.Shield// Debuff.Slow项目配置
启用GAS插件
在 Edit > Plugins 中启用:
- GameplayAbilities — 核心GAS插件
创建AttributeSet
#pragma once#include "CoreMinimal.h"#include "AttributeSet.h"#include "MyAttributeSet.generated.h"
UCLASS()class UMyAttributeSet : public UAttributeSet{ GENERATED_BODY()
public: // 生命值 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes") FGameplayAttributeData Health;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes") FGameplayAttributeData MaxHealth;
// 魔法值 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes") FGameplayAttributeData Mana;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes") FGameplayAttributeData MaxMana;
// 攻击力 UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Attributes") FGameplayAttributeData AttackPower;
// 回调:当属性被修改时触发 virtual void PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data) override;};#include "MyAttributeSet.h"#include "GameplayEffect.h"#include "GameplayEffectExtension.h"
void UMyAttributeSet::PostGameplayEffectExecute(const FGameplayEffectModCallbackData& Data){ if (Data.EvaluatedData.Attribute == GetHealthAttribute()) { SetHealth(FMath::Clamp(GetHealth(), 0.f, GetMaxHealth())); } else if (Data.EvaluatedData.Attribute == GetManaAttribute()) { SetMana(FMath::Clamp(GetMana(), 0.f, GetMaxMana())); }}绑定ASC到Character
UCLASS()class AMyCharacter : public ACharacter{ GENERATED_BODY()
public: UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Abilities") TObjectPtr<UAbilitySystemComponent> AbilitySystemComponent;
UPROPERTY() TObjectPtr<UMyAttributeSet> AttributeSet;
virtual void PossessedBy(AController* NewController) override; virtual void OnRep_PlayerState() override;};#include "MyCharacter.h"#include "MyAttributeSet.h"
void AMyCharacter::PossessedBy(AController* NewController){ Super::PossessedBy(NewController);
if (AbilitySystemComponent) { AbilitySystemComponent->InitAbilityActorInfo(this, this);
// 给ASC注册AttributeSet AbilitySystemComponent->AddAttributeSetSubobject(AttributeSet);
// 赋予初始技能 GiveDefaultAbilities(); }}
void AMyCharacter::OnRep_PlayerState(){ Super::OnRep_PlayerState();
if (AbilitySystemComponent) { AbilitySystemComponent->InitAbilityActorInfo(this, this); }}
void AMyCharacter::GiveDefaultAbilities(){ // 在这里赋予角色的默认技能 // 使用GrantAbility或通过DataAsset配置}实战:创建Fireball技能
步骤1:创建技能蓝图
- 创建
GameplayAbility子类蓝图BP_FireballAbility - 在蓝图编辑器中设置:
- Ability Tags:添加
Damage.Fire - Cooldown:设置冷却时间
- Cost:设置消耗(魔法值)
- Ability Tags:添加
步骤2:实现技能逻辑
UCLASS()class UFireballAbility : public UGameplayAbility{ GENERATED_BODY()
public: // 发射火球 virtual void ActivateAbility(const FGameplayAbilitySpecHandle Handle, FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo& ActivationInfo, FOnGameplayAbilityEnded::FDelegate* OnEnded) override;
// 激活技能的输入事件 UFUNCTION(BlueprintCallable, Category = "Ability") void InputPressed(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo& ActivationInfo);};#include "FireballAbility.h"#include "Abilities/GameplayAbilityTargetActor_SingleLineTrace.h"#include "Abilities/GameplayAbilityTypes.h"
void UFireballAbility::ActivateAbility(const FGameplayAbilitySpecHandle Handle, FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo& ActivationInfo, FOnGameplayAbilityEnded::FDelegate* OnEnded){ // 检查技能是否有效 if (!CommitAbility(Handle, ActorInfo, ActivationInfo)) { EndAbility(Handle, ActorInfo, ActivationInfo, true, false); return; }
// 获取技能所有者 AActor* Owner = ActorInfo->OwnerActor.Get();
// 生成火球逻辑... // 这里可以Spawn一个Actor或播放特效
UE_LOG(LogTemp, Warning, TEXT("Fireball Activated!"));
// 结束技能 EndAbility(Handle, ActorInfo, ActivationInfo, false, false);}
void UFireballAbility::InputPressed(const FGameplayAbilitySpecHandle Handle, const FGameplayAbilityActorInfo* ActorInfo, const FGameplayAbilityActivationInfo& ActivationInfo){ TryActivateAbility(Handle);}步骤3:赋予技能
// 在Character的GiveDefaultAbilities中void AMyCharacter::GiveDefaultAbilities(){ if (!AbilitySystemComponent) return;
// 创建技能Spec FGameplayAbilitySpec Spec; Spec.Ability = NewObject<UFireballAbility>(); Spec.Level = 1;
// 赋予技能 AbilitySystemComponent->GiveAbility(Spec);}冷却系统
设置Cooldown GameplayEffect
// 定义冷却GETSubclassOf<UGameplayEffect> CooldownGE = StaticLoadClass( UGameplayEffect::StaticClass(), nullptr, TEXT("GameplayEffect'/Game/Effects/GE_Cooldown.GE_Cooldown_C'"));
// 检查是否在冷却中bool AMyCharacter::IsAbilityOnCooldown(FGameplayTag AbilityTag){ FGameplayTagContainer OwnedTags; AbilitySystemComponent->GetOwnedGameplayTags(OwnedTags); return OwnedTags.HasTag(AbilityTag);}常见问题
Q: GAS和普通函数调用的区别?
A: GAS提供了完整的生命周期管理、预测系统、网络同步、冷却/消耗验证。普通函数调用没有这些。
Q: AttributeSet为什么要用FGameplayAttributeData而不是float?
A: FGameplayAttributeData支持元属性(MaxHealth)和Clamp设置,能正确处理属性比例修改。
Q: 如何调试GAS?
A: 使用ASC->Debug命令可以在屏幕上显示所有技能和属性的详细信息。
总结
GAS是UE5最强大的技能系统框架,核心组成:
- ASC — 技能系统核心组件
- AttributeSet — 管理角色属性
- GameplayAbility — 定义技能逻辑
- GameplayEffect — 实现buff/debuff
- GameplayTags — 权限控制和识别
建议从官方示例项目入手,熟悉后再自定义实现复杂系统。
参考资源
UE5 Gameplay Ability System (GAS) 完全指南
https://gzhblog.cn/posts/2026-03/2026-03-30-ue5-gas-system/ 写作概览
20 篇
文章
2.9万
总字数
2.5h
阅读时长
1,464
均字数
年度发文
2026 20
Unreal相关
Unity相关
写作概览
20 篇
文章
2.9万
总字数
2.5h
阅读时长
1,464
均字数
年度发文
2026 20
Unreal相关
Unity相关