文章目录
前言
GAS(Gameplay Ability System)是虚幻引擎(Unreal Engine)用于实现角色技能、效果和战斗逻辑的强大框架,广泛应用于RPG、MOBA、FPS 等游戏中。你提到想深入理解 GAS 的底层原理,特别是 GE(GameplayEffect)是如何实现的,我们就从核心架构说起,逐层展开。
一、GAS 底层架构概览
GAS的核心分为以下几个组件:
模块名 | 作用 | 关键类 |
---|---|---|
Attribute System | 属性管理(如血量、攻击力) | UAttributeSet, FGameplayAttribute |
Ability System | 技能管理(主动技能、被动技能) | UGameplayAbility, UAbilitySystemComponent |
Effect System | 效果系统(如造成伤害、加速等) | UGameplayEffect, FGameplayEffectSpec |
Tag System | 标签系统(逻辑判断、触发) | FGameplayTag, FGameplayTagContainer |
Targeting | 目标系统(锁定目标等) | GameplayAbilityTargetActor |
这些模块都由 UAbilitySystemComponent(ASC)统筹管理。每个角色通常都拥有一个 ASC。
二、底层原理详解
-
1.AbilitySystemComponent 是核心大脑
-
注册属性集合:通过 InitStats() 注册 UAttributeSet(如生命、蓝量等)
持有所有 Ability 和 GE 的上下文:包括冷却、施放状态等
处理 RPC / 网络同步:自动在客户端/服务器同步 GE 和属性变化
2.GameplayAbility 的执行流程
-
是一个 Blueprint/C++ 类,可以触发、取消、冷却技能
可以使用 WaitGameplayEvent, WaitTargetData, ApplyGameplayEffectToTarget 等 Task 节点组合逻辑
生命周期核心函数:
virtual void ActivateAbility(...) override;
virtual void EndAbility(...) override;
三、GE(Gameplay Effect)实现原理
1. GE 的创建与应用流程
假设你要对敌人造成伤害:
// 伪代码
FGameplayEffectSpecHandle GEHandle = MakeOutgoingSpec(DamageEffectClass, Level, Context);
ApplyGameplayEffectSpecToTarget(GEHandle, TargetASC);
-
底层流程如下:
-
1.MakeOutgoingSpec() 创建 FGameplayEffectSpec
2.内含 伤害数值(Mods)、标签(Tag)、应用时机(DurationPolicy)
3.ApplyGameplayEffectSpecToTarget() 由 ASC 将 Effect 应用到目标 ASC
4.ASC 调用 ExecuteGameplayEffect() → 修改 AttributeSet 中属性
5.自动同步到客户端(NetMulticast)
2. GE 的内部结构
struct FGameplayEffectSpec {
const UGameplayEffect* Def; // 指向 Effect 配置
FGameplayEffectContextHandle Context;
TArray<FModifierSpec> Modifiers; // 多个属性修改器
FGameplayTagContainer GrantedTags; // 授予目标的标签
DurationPolicy Duration; // 持续类型(Instant, Duration, Infinite)
};
Modifier 定义了:修改哪个属性、用什么运算符(Add、Mult、Override)、值是多少
ExecutionCalculation:自定义复杂公式(如暴击、抗性)
ModifierMagnitude 可绑定到 Attribute, CurveTable, Custom Calculation
四、属性如何更新与同步
-
属性更新流程(以造成伤害为例)
-
1.GE 修改了属性(如 Health)
2.ASC 调用 PostGameplayEffectExecute(),触发逻辑(如死亡、UI更新)
3.NetDeltaSerialize + FGameplayAttributeData 结构体 → 自动同步
UPROPERTY(EditAnywhere, BlueprintReadWrite, ReplicatedUsing = OnRep_Health)
FGameplayAttributeData Health;
这比手动 RPC 更高效且自动。
五、Execution Calculation 是实现伤害计算的关键
如果伤害公式复杂(如暴击 = 基础伤害 * (1+暴击率) - 护甲),推荐用:
class UMyDamageExecution : public UGameplayEffectExecutionCalculation
Override Execute_Implementation
读取属性(攻、防、暴击等)
写入 Modifier 输出
这样实现就类似于一个数据驱动的“脚本”系统。
六、例子:造成伤害 GE 的生命周期
-
玩家点击攻击键 → 触发 UGameplayAbility::ActivateAbility()
-
调用 ApplyGameplayEffectToTarget() 应用伤害 GE
-
创建 FGameplayEffectSpec → 带有攻击力、标签等上下文
-
应用到目标 ASC
-
修改 Health,判断是否死亡
-
同步属性给客户端 → 刷新 UI 血条
七、开发建议
需求 | 建议做法 |
---|---|
批量技能配置 | 用 DataTable 驱动 GA/GE 生成 |
自定义技能逻辑 | GA 中组合多个 Task 执行 |
多人游戏同步 | ASC、AttributeSet 均支持 Replication |
限制 GE 应用条件 | 用 Tag 限制、或 ConditionalGameplayEffect |