[UnrealOpenDay2020] 深入GAS架构设计 | EpicGames 大钊

[UnrealOpenDay2020] 深入GAS架构设计 | EpicGames 大钊

本期将深入 GAS 相关内容,涉及 GAS 内部类图关系、核心概念和结构等

传送门:[UnrealOpenDay2020]深入GAS架构设计 | EpicGames 大钊



一. GAS 基础

1.1 GAS 概述

  1. GAS:全称 Game Ability System 游戏技能系统
  • 是 EPIC 从 Paragon 和 Fortnite 开始,为满足自己游戏项目开发和使用的游戏技能框架系统,之后不断迭代、优化,封装为内置插件以供使用

  • GAS 是在 UE 自身 GamePlay 之外的一套框架,可配合 GamePlay 框架和 AI 模块(行为树)一起使用

  • GAS 支持联机游戏中的网络复制和预测机制,服务器上的技能逻辑可以广播到客户端上展示,客户端技能也可以在本地先执行,若服务器预测不通过,则可以在客户端上回滚操作
    1.1-1GAS 概述


  1. GAS 的使用时机 :
Strong(优势) Weak(劣势)
灵活易扩展,可实现复杂的技能流程 大量的概念和类,学习曲线陡峭
支持联机复制(属性复制、RPC广播)和动作预测回滚 重度 C++,对 BP 不够友好
解耦,易于团队协作和项目复用 需要按照框架定义一堆类才能开始启动
细粒度思考实现单个动作逻辑 GAS 的网络服务必须配合 DS
数据驱动、数值配置 实践演化框架,可选插件,文档不足
已帮你处理繁杂流程麻烦逻辑 要求技术功底高,源码 Debug 能力强
人多 - 大项目 - 多技能 - 联机 - 技术强 - 重表现 人少 - 小项目 - 少技能 - 单机 - 技术弱 - 弱表现

3. GAS 开发初衷是处理联机环境下的复杂技能逻辑

1.2 如何设计一个易于拓展的技能系统

抛开 GAS,设计一个易于拓展的技能系统,需要分析一个技能里包含哪些元素:

  1. 逻辑部分
  • 技能的获得和释放

  • 触发判断的条件

  • Buff 系统

  1. 视听部分
  • 动作动画

  • 特效

  • 声效

  1. 数据部分
  • 数值计算

  • 数据配置


  1. 如何考虑网络联机同步?
  • 设计模式的本质是抽象变化,因此解耦技能系统中可以变化的部分,独立变化

  • 技能包含变化的部分较多,GAS 设计的概念和类也比较多,如:

    • UAbilitySystemComponent - ASC

    • UGameplayAbility - GA

    • UGameplayEffect - GE

    • UGameplayCueNotify - GC

    • FGameplayAttribute - Attribute

    • FGameplayTag - Tag

    • UGameplayTask - Task

    • FGameplayEventData - Event



1.3 GAS 核心概念

  1. UAbilitySystemComponent(ASC):能力系统组件(技能系统组件),缩写 ASC,只有拥有 ASC 的 Actor 才拥有管理释放技能的能力,ASC 也负责管理其他的技能部分

  2. UGameplayAbility(GA):技能逻辑,定义一个技能的主体逻辑

  3. UGameplayEffect(GE):游戏效果,这个效果一般是进行属性修改或动作效果触发

  4. UGameplayCueNotify(GC):游戏特效,包含一次性特效(如:爆炸)、持续性特效(如:持续燃烧)

  5. FGameplayAttribute(Attribute):游戏属性,描述生命值、攻击力、防御力等,多个 Attribute 组成 AttributeSet,挂在 Actor 上

  6. FGameplayTag(Tag):游戏标签,是广泛使用且功能强大的标签系统,通过给类和对象挂上标签,就可以层次化地判断和搜索各个条件

  7. UGameplayTask(Task):GAS 中异步操作的节点(如:在技能中播放蒙太奇,需要等蒙太奇结束后再结束技能,此时就需要异步操作)

  8. FGameplayEventData(Event):ASC之间可以通过游戏事件来通知对方



1.4 一个技能的自我修养

  • Who:谁能放技能?AbilitySystemComponent

  • How:技能的逻辑?GameplayAbility

  • Change:技能的效果?GameplayEffect

  • What:技能改变的属性?GamePlayAttribute

  • If:技能涉及的条件?GameplayTag

  • Visual:技能的视效?GameplayCue

  • Async:技能的长时行动(异步)?GameplayTask

  • Send:技能消息事件?GamePlayEvent



二. GAS 核心结构

  • 蓝色的 GameplayTag 和 GameplayTask 都是独立的模块,其本身可以脱离 GAS 存在,可被单独引用,也可以单独学习分析(初学 GAS 可以从这里开始,代码量较少,可以快速对 GAS 基础设施有概念)

  • GameplayTag 和 GameplayTask 都被 GameplayAbility.uplugin 核心插件引用(AI 模块也引用了 GameplayTag 和 GameplayTask)

  • 同时,绿色的 Editor 模块引用了蓝色的 Runtime 模块,Editor 模块主要是实现编辑 UI,提供了在编辑器里遍历的编辑方式

image



2.1 GameplayTag 游戏标签

  • 层次化的字符串标签(通过. 符号,区分父子级)

  • 轻量 FName,可附加到各类上(如:GameplayEffect、GameplayAbility、GameplayCue、GameplayEventData)做搜索条件

  • 整体所有 Tag 构成一颗 Tag 树,存放在 UGameplayTagsManager 下,方便快速查找

image


组合Tag,灵活的逻辑查询 Tags:

  • 多个 Tag 被组合起来构成一个 FGameplayTagContainer

  • 也可以被组合在一起,加上逻辑操作符作为一个 TagQuery

  • 一个 Tag 和一个 GameplayTagNode (树节点)相关联

image



2.2 GamePlayAttribute 游戏属性

  • float BaseValue:基础值,非最大值,永久值

  • float CurrentValue:当前值,Buff 叠加后的值,临时值

  • 数据配置上,可从 DataTable 或 CurveTable 中读取值,AttributeSet 可定义多个/多套属性值

image



2.3 GameplayEffect 技能效果

  • 决定一个技能的“逻辑效果”

  • 纯配置蓝图,不需要重载函数

  • GameplayEffect(GE)是修改 Attribute 的唯一合法通道,所有 Attribute 改动必须经此流程,以便让 GE 完整跟踪修改过程,触发对应事件回调,实现对属性变更的统一管控,禁止任何手动直接修改 Attribute 的操作

  • GE 配置功能包括:类型、修改器、周期、应用需求、溢出处理、过期处理、显示处理、Tags 条件、免疫、堆叠、能力赋予...

image


  • UGameplayEffect 只是作为一个数据模版,“Spec”才是每次 Apply 后生成的实例

    • UGameplayEffect 由 FGameplayModifierInfo(属性栏修改器)和 FGameplayEffectCue (GE 触发的 Cue 行为)组成

    • 在 GameplayAbility 调用 Apply 时,GameplayEffect 生效,每次调用 Apply 都会产生一个 FGameplayEffectSpec(GE 的实例)

    • FGameplayEffectSpec 自带等级,等级决定不同技能属性值,每个 Spec 对应一个 Active 实例,最终通过组合,存储到 ASC 里面

    • 简言之:模板(UGameplayEffect)→实例化(Apply 出 Spec )→组合存储(进 ASC )

image

image



2.4 GameplayCue 技能特效

  • 决定一个技能的“视觉效果”

  • 可全局配置 Tag-Handler 的映射(Tag 和继承自 UGameplayCueNotity 特效播放器的一一对应)

  • 可通过 Effect 触发,也可 GA 手动触发

  • Cue分为:Static 一次性、Actor 持久

  • 可在 Cue 的重载函数里编写蓝图节点,触发粒子特效/音效,常见重载,如:OnActive、WhileActive、Executed、Removed

image


  • Cue 可在 GE 中配置触发,或在 GA 里调用 Execute/Add 触发,触发后生成的实例存储在 FGameplayCueObjectLibrary 对象库,以提供后续复用,减少触发时延迟

  • Cue 的触发分为:

    • Static Cue:直接在 CDO 上调用(不要在 Cue 里保存状态,不会生成新对象)

    • Actor Cue:触发 Spawn,生成新实例

  • 生效的 Cue 最终在 ASC 里面引用保存

image



2.5 GameplayAbility 游戏技能

  • “技能”是很广义的抽象

  • 基础移动、射线检测、UI 交互,不是技能,GAS 中的技能用于表示专门触发某一件事情,而不是平时一直在做的事

  • 在不同的 Actor 上学习、取消、释放不同技能,构成了主体逻辑

  • 写主体逻辑的地方

  • 可重载函数及回调:ActiveAbility 激活、CommitAbility 提交、CancelAbility 取消、EndAbility 结束

image


  • UGameplayAbility 可用 CDO 模板,也可生成实例保存状态

  • Spec 是技能学习后,带等级的“实例”

    • UGameplayAbility可以通过调用 TryActiveAbility,在外部被 OwnerActor 触发

    • 自身不需要保存状态的 UGameplayAbility,可用 CDO 模板直接调用,若是需要每次实例化都跟踪不同状态,可选择每次生成新 Spec 实例(带等级,等级传递给 GE 触发对应技能属性值),激活后的 GA 保存在 ASC

image

image



2.6 GameplayTask 游戏异步任务

  • 执行异步任务的框架

  • Task 框架本身是比较基础的模块,可在 GAS 外被单独使用,只需添加 GameplayTaskComponent

  • 可用于异步长时动画的触发和等待

  • 已经预实现好了一系列常用 Tasks

  • 可重载:Activate、TickTask

image


  • UAbilityTask 继承自 UGameplayTask,并实现了一系列 Task

    • UAbilityTask 相较父类,多了 GA 引用

    • 这些 Task 都在 ASC 中执行(ASC 是继承于 Task 组件的)

image



2.7 GameplayEvent 游戏事件

  • 手动触发游戏类型

  • 不同事件靠 Tag 识别,可携带 Payload 数据

  • 可触发技能

  • 在另一端可等待具体 Tag 事件触发

image


  • GA 在 WaitGameplayEvent 时,向 ASC 注册回调,通过 Tag 映射识别

  • 外部其他 GA 调用 SendGameplayEvent 时,使用 EventTag 在 ASC 映射表中检索,检索成功后触发回调

image



2.8 AbilitySystemComponent 游戏技能组件

  • ASC 是技能系统运行的核心,负责管理协调其他部件:Ability、Effect、 Attribute、 Task、 Event...这些交互都在 ASC 里做记录和转发

  • 只有拥有 ASC 的 Actor 才拥有释放技能的能力

  • ASC 放在 Pawn 还是 PlayerState 上,这是个问题

    • 联机游戏,推荐放在 PlayerState 上,会复制到各个端且会一直存在(Pawn 重生后可能会丢失状态)

    • 单机游戏/简单项目,放在 Pawn 上也可以

image


  • 技能互相作用:其实就是一个 Actor 上的 ASC 作用到另一个 Actor 上的 ASC,其互相增删 Effect、触发 Cue、互相给对方贴标签等

    • ASC 继承自 UGameplayTaskComponent,有执行 Task 的能力,同时还实现了多个接口

    • ASC 挂在 OwnerActor 上,初始化时,寻找 OwnerActor 上的 AttributeSet 注册起来

    • ASC 是技能框架运行的核心,GAS 提供的功能,大部分接口可以在 ASC 头文件中找到

image



三. 小结

  • Actor 之间通过 ASC 来相互交互

  • ASC 最重要的类是 GameplayAbility

    • GA 可以给对方 ApplyEffect,也可以 Add/Execute Cue 播放特效。而 Effect 的生效又可以修改 AttributeSet 中的属性,或赋予新的 GA

    • GA 在执行时,发起 Task 进行异步操作,或给对方 Actor 的 ASC 手动 Event 事件通知

image

posted @ 2025-06-27 19:10  哟吼--小文文公主  阅读(652)  评论(0)    收藏  举报