战斗流

本文简对GCS战斗系统中的攻防流程进行介绍,用于帮助你更好地使用GCS。

Cover.GCS
作

作者

作者

创建时间: 2025年4月15日更新时间: 2026年4月14日

目录

战斗流

CombatFlow是一个UObject,每一个战斗系统组件可以指定一个CombatFlow。

你应该继承内置的GCS_BaseCombatFlow,并重写相关函数以实现你的自定义逻辑,或者参考现有的CombatFlow并创建一个全新的。

处理属性变更

在游戏性属性中提到,属性系统组件(GGA_AttributeSystemComponent)会将所有属性变更的回调转发到CombatFlow进行处理。因此你只需要重写HandleGameplayEffectExecute即可。

战斗(攻防)系统.004
如何处理属性,并产生什么样的攻击结果,完全由你自己的游戏机制决定,而参考实现中提供了魂类游戏常见的流程。

产生攻击结果

当你在HandleGameplayEffectExecute中针对属性变化进行处理后,你应该根据你自己的游戏逻辑,将该过程中的信息转换成攻击结果,并注册到战斗系统组件。

战斗(攻防)系统.005
例如:在处理完IncomingDamage后,你应该把相关信息构造为AttackResult结构体,并注册到战斗系统上。TaggedValues即包含了此过程中产生的一些信息,如“实际变化的血量”等。你也可以在这里

自定义CombatFlow

攻击者可以发起不同的攻击请求,但每一个目标对每一个攻击请求可能有不同的 “处理”。你可以通过自定义GCS_CombatFlow实现不同的攻击处理流程,并在CombatSystemComponent上配置不同的CombatFlow Class。

假设一种箭射向敌人,通常,它应该会触发命中反应。但是假设你的敌人体型很大,以至于你不希望他做出反应。这时你就可以指定不同的CombatFlow,而无需在攻击者层面进行大量的If/Else判断。

何时采用完全不同的CombatFlow?

1.你不希望一条狗可以弹反你的进攻。

2.你不希望超巨大的Boss会因为你帮他的脚挠痒而摔倒。

3.你不希望一个建筑物能够闪避你的进攻。

在战斗流程中访问攻击请求

攻击请求本身随着GameplayEffectContext在不同的流程中进行传递,意味着你可以随时随时地访问攻击请求中中配置的各种信息。

比如你可以通过Context拿到攻击请求对象,并获取其关联的攻击定义。

战斗(攻防)系统.010

GoodToKnow

攻击请求是一个实例化的UObject,意味着它不是运行时创建的,而是在编辑器中创建并存储到硬盘上,这是它能高效地通过网络传输的秘诀。

攻击请求是Const类型,意味着它只能存储静态数据供游戏逻辑使用,你不应该在游戏运行时修改它。

如果你在蓝图定义一个AttackRequest类型的变量,你可以看到它允许你内联创建一个实例并随着Outer资产的保存而保存。

战斗(攻防)系统.011
战斗(攻防)系统.012

攻击结果

每当CombatFlow处理完一次受到的攻击后,会产生攻击结果,并记录到战斗系统组件上,且通过网络同步到客户端。

每当一个战斗结果生成后,GCS都会根据其内容触发不同的战斗反馈,比如播放HitReaction,播放GameplayCue产生视觉效果等等。

处理攻击结果

在CombatFlow中,你可以以数据驱动的方式 配置不同的AttackResultProcessors(攻击结果处理器)来根据不同的攻击结果进行不同的处理。

战斗(攻防)系统.014
战斗(攻防)系统.015

你可以查看GCS_BaseCombatFlow蓝图了解具体的用法。

内置处理器

Send Gampelay Event(发送游戏事件)

它允许您根据攻击结果向攻击者/受害者发送不同的游戏事件。

战斗(攻防)系统.016

您还可以使用 TagQuery 来产生不同的逻辑分支。

比如: 当攻击结果的SourceTags中包含Block标签时,才会触发防御时的受击反应. 当攻击结果的SourceTags中包含Hit标签时,才会触发被击中时的受击反应。

自定义“攻击结果处理器”

你通过创建GCS_AttackResultProcessor的子类来构建新的处理器。

比如:你可以创建一个“伤害统计处理器”,将每一次受到的攻击的结果记录到别的其他的系统,(比如一个Log系统,或者战报系统,可以将消息发送到UI。)