虚幻GAS底层原理解剖二 (GE)

发布于:2025-08-07 ⋅ 阅读:(10) ⋅ 点赞:(0)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言

将从 源码层级 深入解析 GameplayEffect (GE) 的实现原理,包含它的创建、应用、执行计算、网络同步等关键机制。适合高级开发者理解和定制自己的 GAS 系统。

一、GE 的本质:数据驱动的属性修改器

UGameplayEffect 是一个 定义属性变化、状态添加、标签赋予、持续时间 等的配置类,关键特点是:
数据驱动:你只需要配置即可完成数值逻辑
与 ASC 和 AttributeSet 协同工作
支持自定义计算与条件判断(Execution Calculation)

二、GE 的应用机制:底层调用链

以下是 GE 从配置到生效的流程图,先从整体上把握:

+--------------------------+
|     UGameplayEffect     | ← 蓝图/资源中定义
+--------------------------+
             |
             v
+--------------------------+
|  FGameplayEffectSpec     | ← 创建实例(带上下文和数值)
+--------------------------+
             |
             v
+--------------------------+
| ApplyGameplayEffectTo... |ASC 接收并执行 GE
+--------------------------+
             |
             v
+--------------------------+
| AttributeSet & Tags      | ← 属性变化、标签赋予、调用回调
+--------------------------+

三、核心类结构与成员详解

  1. UGameplayEffect(配置类)
    定义了以下关键属性:
// 修改器
UPROPERTY(EditDefaultsOnly, Category = "Modifiers")
TArray<FGameplayModifierInfo> Modifiers;

// 持续时间类型(即时、持续、无限)
UPROPERTY(EditDefaultsOnly, Category = "Duration")
EGameplayEffectDurationType DurationPolicy;

// 自定义计算逻辑
UPROPERTY(EditDefaultsOnly, Category = "Execution")
TArray<TSubclassOf<UGameplayEffectExecutionCalculation>> Executions;
  1. FGameplayEffectSpec(运行时 GE 实例)
    这个结构是 GE 的实际运行体(含上下文、动态值等),由 ASC 创建:
FGameplayEffectSpecHandle MakeOutgoingSpec(const UGameplayEffect* InDef, float Level, FGameplayEffectContextHandle Context);

重要成员:

const UGameplayEffect* Def;
TArray<FModifierSpec> Modifiers;
FGameplayEffectContextHandle EffectContext;
FGameplayTagContainer CapturedSourceTags;
FGameplayTagContainer CapturedTargetTags;

Level:驱动 GE 中数值表达式(如从 CurveTable 读数值)
Context:包含技能释放者、目标等(如爆炸中心)

四、GE 中的属性修改器原理(Modifier)

每个 Modifier 表示一次属性变化:

struct FGameplayModifierInfo {
  FGameplayAttribute Attribute;       // 要修改的属性(如 Health)
  EGameplayModOp::Type ModifierOp;    // 操作类型(Add, Multiply, Override)
  FScalableFloat Magnitude;           // 修改值,支持曲线或 Execution 计算
  FGameplayTagContainer SourceTags;
  FGameplayTagContainer TargetTags;
}

这些 Modifier 最终被封装进 FModifierSpec 并生效在目标 AttributeSet 上。

五、自定义伤害公式:Execution Calculation 原理

你可以扩展 UGameplayEffectExecutionCalculation 来实现暴击、护甲穿透、真实伤害等。
实现流程:

  1. GE 中添加 Executions 数组,填入你的子类
  2. 继承并 override:
void Execute_Implementation(const FGameplayEffectCustomExecutionParameters& ExecParams, FGameplayEffectCustomExecutionOutput& OutSpec) const override;
  1. 使用 ExecParams 读取源和目标属性:
FAggregatorEvaluateParameters EvalParams;
float SourceAttack = 0.0f;
ExecParams.AttemptCalculateCapturedAttributeMagnitude(AttackDef, EvalParams, SourceAttack);
  1. 设置输出:
OutSpec.AddOutputModifier(FGameplayModifierEvaluatedData(HealthProperty, EGameplayModOp::Additive, -FinalDamage));

六、GE 应用到角色的过程(代码流)

以 ApplyGameplayEffectToTarget() 为例:


// UAbilitySystemComponent.cpp
FActiveGameplayEffectHandle UAbilitySystemComponent::ApplyGameplayEffectSpecToTarget(const FGameplayEffectSpec& Spec, UAbilitySystemComponent* TargetASC)

流程如下:

  1. 校验 GE 和目标合法性
  2. 如果 GE 为 Instant:
    直接执行 ExecuteGameplayEffect(),修改目标属性
  3. 如果为 Duration 或 Infinite:
    创建 FActiveGameplayEffect,加入 ActiveGameplayEffectsContainer
    设置定时器、调用 Tick(),周期性生效
  4. 网络同步(见第七节)

七、网络同步原理

GAS 强调属性变化的带宽优化与正确同步:

  1. 属性同步机制
    使用了 FGameplayAttributeData + OnRep_* + NetDeltaSerialize
UPROPERTY(ReplicatedUsing = OnRep_Health)
FGameplayAttributeData Health;

同步只在属性值变动时触发,且为压缩格式传输。

  1. GE 同步机制
GE 本身用 FActiveGameplayEffectHandle 表示,并存储在 FActiveGameplayEffectsContainer 中。
使用 FGameplayEffectSpec::NetSerialize() 传递
ASC 会同步 GE 应用情况给所有客户端,触发视觉效果

八、持续型与无限型效果的 Tick 原理

if (Effect.DurationPolicy == EGameplayEffectDurationType::HasDuration) {
    World->GetTimerManager().SetTimer(TimerHandle, this, &ApplyEffectPeriodically, Period, true);
}

每 Period 时间调用一次 ExecuteGameplayEffect()
Tick 中可以继续触发属性变化(如中毒、持续回血)

九、GE 生命周期中的回调与接口

可以监听以下事件来响应 GE 应用:

回调位置 方法名 说明
AttributeSet PostGameplayEffectExecute() GE 执行完毕后触发,常用于处理死亡逻辑
ASC OnActiveGameplayEffectAddedDelegateToSelf 自身被应用 GE 时调用
GE GameplayEffectExecutionCalculation::Execute_Implementation() 自定义计算时执行

十、GAS 常见设计模式(经验)

目标 做法
动态属性值(攻击受等级影响) Modifier 使用 CurveTable
多个 Modifier 多段伤害 GE 嵌套另一个 GE
特殊效果组合(燃烧+眩晕) 使用 Tag + ConditionalGE
技能脚本编排 GA 中组合多个 GE 和 Task

总结:GE 核心是“数据 + 执行器”

  1. UGameplayEffect:定义数据模板(属性变动、时效、标签)

  2. FGameplayEffectSpec:具体执行实例,包含上下文、数值等

  3. UGameplayEffectExecutionCalculation:复杂数值逻辑处理器

  4. UAbilitySystemComponent:调度器,负责 GE 应用、Tick、同步等

  5. AttributeSet:属性存储与同步容器


网站公告

今日签到

点亮在社区的每一天
去签到