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

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

文章目录

  • 前言
  • [一、GE 的本质:数据驱动的属性修改器](#一、GE 的本质:数据驱动的属性修改器)
  • [二、GE 的应用机制:底层调用链](#二、GE 的应用机制:底层调用链)
  • 三、核心类结构与成员详解
  • [四、GE 中的属性修改器原理(Modifier)](#四、GE 中的属性修改器原理(Modifier))
  • [五、自定义伤害公式:Execution Calculation 原理](#五、自定义伤害公式:Execution Calculation 原理)
  • [六、GE 应用到角色的过程(代码流)](#六、GE 应用到角色的过程(代码流))
  • 七、网络同步原理
  • [八、持续型与无限型效果的 Tick 原理](#八、持续型与无限型效果的 Tick 原理)
  • [九、GE 生命周期中的回调与接口](#九、GE 生命周期中的回调与接口)
  • [十、GAS 常见设计模式(经验)](#十、GAS 常见设计模式(经验))
  • [总结:GE 核心是"数据 + 执行器"](#总结:GE 核心是“数据 + 执行器”)

前言

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

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

:
数据驱动:你只需要配置即可完成数值逻辑

复制代码
与 ASC 和 AttributeSet 协同工作   

支持自定义计算与条件判断(Execution Calculation)

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

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

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

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

  1. UGameplayEffect(配置类)
    定义了以下关键属性:
cpp 复制代码
// 修改器
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 创建:
cpp 复制代码
FGameplayEffectSpecHandle MakeOutgoingSpec(const UGameplayEffect* InDef, float Level, FGameplayEffectContextHandle Context);

重要成员:

cpp 复制代码
const UGameplayEffect* Def;
TArray<FModifierSpec> Modifiers;
FGameplayEffectContextHandle EffectContext;
FGameplayTagContainer CapturedSourceTags;
FGameplayTagContainer CapturedTargetTags;

Level:驱动 GE 中数值表达式(如从 CurveTable 读数值)

Context:包含技能释放者、目标等(如爆炸中心)

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

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

cpp 复制代码
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:
cpp 复制代码
void Execute_Implementation(const FGameplayEffectCustomExecutionParameters& ExecParams, FGameplayEffectCustomExecutionOutput& OutSpec) const override;
  1. 使用 ExecParams 读取源和目标属性:
cpp 复制代码
FAggregatorEvaluateParameters EvalParams;
float SourceAttack = 0.0f;
ExecParams.AttemptCalculateCapturedAttributeMagnitude(AttackDef, EvalParams, SourceAttack);
  1. 设置输出:
cpp 复制代码
OutSpec.AddOutputModifier(FGameplayModifierEvaluatedData(HealthProperty, EGameplayModOp::Additive, -FinalDamage));

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

以 ApplyGameplayEffectToTarget() 为例:

cpp 复制代码
// 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
cpp 复制代码
UPROPERTY(ReplicatedUsing = OnRep_Health)
FGameplayAttributeData Health;

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

  1. GE 同步机制

:
使用 FGameplayEffectSpec::NetSerialize() 传递

复制代码
ASC 会同步 GE 应用情况给所有客户端,触发视觉效果

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

cpp 复制代码
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:属性存储与同步容器

相关推荐
RReality41 分钟前
【Unity Shader URP】Matcap 材质捕捉实战教程
java·ui·unity·游戏引擎·图形渲染·材质
魔士于安1 小时前
unity urp材质球大全
游戏·unity·游戏引擎·材质·贴图·模型
南無忘码至尊4 小时前
Unity学习90天 - 第 6 天 -学习物理 Material + 重力与阻力并实现弹跳球和冰面滑动效果
学习·unity·游戏引擎
mxwin6 小时前
Unity 单通道立体渲染(Single Pass Instanced)对 Shader 顶点布局的特殊要求
unity·游戏引擎·shader
魔士于安8 小时前
unity 低多边形 无人小村 木质建筑 晾衣架 盆子手推车,桌子椅子,罐子,水井
游戏·unity·游戏引擎·贴图·模型
RReality8 小时前
【Unity Shader URP】简易卡通着色(Simple Toon)实战教程
ui·unity·游戏引擎·图形渲染·材质
魔士于安9 小时前
unity 骷髅人 连招 武器 刀光 扭曲空气
游戏·unity·游戏引擎·贴图·模型
洛阳吕工11 小时前
从 micro-ROS 到 px4_ros2:ROS2 无人机集成开发实战指南
游戏引擎·无人机·cocos2d
风酥糖11 小时前
Godot游戏练习01-第29节-游戏导出
游戏·游戏引擎·godot
南無忘码至尊12 小时前
Unity学习90天-第7天-学习委托与事件(简化版)
学习·unity·游戏引擎