战斗流
CombatFlow是一个UObject,每一个战斗系统组件可以指定一个CombatFlow。
你应该继承内置的GCS_BaseCombatFlow,并重写相关函数以实现你的自定义逻辑,或者参考现有的CombatFlow并创建一个全新的。
处理属性变更
在游戏性属性中提到,属性系统组件(GGA_AttributeSystemComponent)会将所有属性变更的回调转发到CombatFlow进行处理。因此你只需要重写HandleGameplayEffectExecute即可。

如何处理属性,并产生什么样的攻击结果,完全由你自己的游戏机制决定,而参考实现中提供了魂类游戏常见的流程。
产生攻击结果
当你在HandleGameplayEffectExecute中针对属性变化进行处理后,你应该根据你自己的游戏逻辑,将该过程中的信息转换成攻击结果,并注册到战斗系统组件。

例如:在处理完IncomingDamage后,你应该把相关信息构造为AttackResult结构体,并注册到战斗系统上。TaggedValues即包含了此过程中产生的一些信息,如“实际变化的血量”等。你也可以在这里
自定义CombatFlow
攻击者可以发起不同的攻击请求,但每一个目标对每一个攻击请求可能有不同的 “处理”。你可以通过自定义GCS_CombatFlow实现不同的攻击处理流程,并在CombatSystemComponent上配置不同的CombatFlow Class。
假设一种箭射向敌人,通常,它应该会触发命中反应。但是假设你的敌人体型很大,以至于你不希望他做出反应。这时你就可以指定不同的CombatFlow,而无需在攻击者层面进行大量的If/Else判断。
何时采用完全不同的CombatFlow?
1.你不希望一条狗可以弹反你的进攻。
2.你不希望超巨大的Boss会因为你帮他的脚挠痒而摔倒。
3.你不希望一个建筑物能够闪避你的进攻。
在战斗流程中访问攻击请求
攻击请求本身随着GameplayEffectContext在不同的流程中进行传递,意味着你可以随时随时地访问攻击请求中中配置的各种信息。
比如你可以通过Context拿到攻击请求对象,并获取其关联的攻击定义。

GoodToKnow
攻击请求是一个实例化的UObject,意味着它不是运行时创建的,而是在编辑器中创建并存储到硬盘上,这是它能高效地通过网络传输的秘诀。
攻击请求是Const类型,意味着它只能存储静态数据供游戏逻辑使用,你不应该在游戏运行时修改它。
如果你在蓝图定义一个AttackRequest类型的变量,你可以看到它允许你内联创建一个实例并随着Outer资产的保存而保存。


攻击结果
每当CombatFlow处理完一次受到的攻击后,会产生攻击结果,并记录到战斗系统组件上,且通过网络同步到客户端。
每当一个战斗结果生成后,GCS都会根据其内容触发不同的战斗反馈,比如播放HitReaction,播放GameplayCue产生视觉效果等等。
处理攻击结果
在CombatFlow中,你可以以数据驱动的方式 配置不同的AttackResultProcessors(攻击结果处理器)来根据不同的攻击结果进行不同的处理。


你可以查看GCS_BaseCombatFlow蓝图了解具体的用法。
内置处理器
Send Gampelay Event(发送游戏事件)
它允许您根据攻击结果向攻击者/受害者发送不同的游戏事件。

您还可以使用 TagQuery 来产生不同的逻辑分支。
比如: 当攻击结果的SourceTags中包含Block标签时,才会触发防御时的受击反应. 当攻击结果的SourceTags中包含Hit标签时,才会触发被击中时的受击反应。
自定义“攻击结果处理器”
你通过创建GCS_AttackResultProcessor的子类来构建新的处理器。
比如:你可以创建一个“伤害统计处理器”,将每一次受到的攻击的结果记录到别的其他的系统,(比如一个Log系统,或者战报系统,可以将消息发送到UI。)
