跳转到正文

注册第一条攻击结果

作

作者

作者

创建时间: 2026年10月21日更新时间: 2026年10月21日

目录

注册第一条攻击结果

本篇做出最小结算闭环:派生一个可实例化的 UGCS_CombatFlow,在目标角色上把 GGA 的属性 execute 回调转到 HandleGameplayEffectExecute,拼出 FGCS_AttackResult 并 RegisterAttackResult。做完后,Debugger 的 Attack Result 段出现最近一条结果,Default Processor 跑一次。近战窗口和子弹发射不在本篇。

相关文档:运行链路见 战斗流程与攻击结果,Processor 策略见 处理器与战斗钩子。GGA 属性回调见 GGA 文档的属性集与生成器。

前置条件

  1. 已按 挂上战斗组件 挂好 UGCS_CombatSystemComponent,权威端已 InitializeAbilitySystem,Globals 是 UGGA_AbilitySystemGlobals。
  2. 目标 Actor 上有 UGGA_AttributeSystemComponent,并且已授予会经 UGGA_AttributeSetEventBridge 转发 PostGameplayEffectExecute 的 AttributeSet。GGA 的 UAS_Health / UAS_Combat,以及 GCS 的 UAS_Poise,都满足这条。自己写的 AttributeSet 若没有转发,后面的 Flow 永远收不到回调。
  3. 准备一个瞬时 Gameplay Effect,它必须改某个属性的 Base Value(例如 UAS_Health 的 Health 或 IncomingDamage)。只加 Tag、不加 execute 修饰的 Duration Effect 不会进入 PostExecute。
  4. 准备一行 FGCS_AttackDefinition,TargetEffectClass 指向上面的瞬时 GE。

插件不会在属性回调里自动调用 HandleGameplayEffectExecute。Combat 组件只把 Globals 的 PreApply 转给 Flow。PostExecute 要项目自己接到 Flow。

1. 派生 Combat Flow 并放一条 Processor

新建蓝图,父类选 UGCS_CombatFlow(显示名 GCS Combat Flow)。基类是 Abstract,不能填进 CombatFlowClass。

在类默认值的 AttackResultProcessors 里加一条 UGCS_AttackResultProcessor_GameplayEvent 或 UGCS_AttackResultProcessor_GameplayCue:

  • ExecutePolicy 用 Default。
  • Event Processor 填至少一个 EventTriggers;Cue Processor 填至少一个 Cue 标签,或让攻击定义的 TargetGameplayCues 非空。
  • 不要加 UGCS_AttackResultProcessor_Death。它的原生实现是空的,第一次执行只打 Warning。

Processor 必须出现在这个子类的实例上。只改 CDO、却把 CombatFlowClass 指到另一个空子类,列表仍是空的。

把该蓝图填进目标 UGCS_CombatSystemComponent 的 CombatFlowClass。权威端 BeginPlay 会 NewObject 出 Flow 并复制给客户端。

2. 把 GGA 回调转到 Flow

目标 Actor 上,用下面任一入口把 FGGA_GameplayEffectModCallbackData 交给 Flow。两条路都有效,选一条即可。

入口

做法

蓝图绑定

监听 UGGA_AttributeSystemComponent 的 OnPostGameplayEffectExecute。取出 Get Combat Flow,调用 Handle Gameplay Effect Execute,把同一份 Payload 传进去。

项目 AttributeSystem 子类

覆写 HandlePostGameplayEffectExecute,同样 GetCombatFlow()->HandleGameplayEffectExecute(Payload)。

Payload.TargetActor 应是被改属性的那个 Actor。在它上面取 Combat 组件。AttributeSystem 找不到时,EventBridge 静默丢掉转发,Flow 不会收到任何调用。

Instant GE 挂了 UGCS_GEComponent_PredictivelyExecute 时,本地预测 execute 也会进同一条绑定。本篇先用权威端瞬时 GE 验证,不要同时打开预测。

3. 在 Flow 里注册结果

在 Flow 子类覆写 HandleGameplayEffectExecute(蓝图事件同名)。基类实现是空的:只接线、不覆写,容器里仍然没有结果。

最小填写:

  1. 新建 FGCS_AttackResult。
  2. EffectContextHandle ← Payload.ContextHandle。
  3. AggregatedSourceTags / AggregatedTargetTags ← Payload 里同名容器。
  4. OptionalObject 本篇留空。
  5. 对所属 UGCS_CombatSystemComponent 调用 RegisterAttackResult。

RegisterAttackResult 只接受权威端,或 Context 标了预测的本地结果。客户端丢进一条既不权威也不预测的结果会被拒绝并 Warning。

插件不会替你判断“这次 execute 算不算一次攻击”。治疗、回蓝、扣耐力只要走到 PostExecute,也会进这个函数。第一次接入可以先全部注册;正式项目通常用 Get Attack Definition Handle 读 Context,句柄无效就直接返回,避免非战斗 GE 也进容器。

不要在这里再 Apply 一条 GE,也不要手写 HandleAttackResult。RegisterAttackResult 写入 FastArray 后,默认实现会按 Processor 的 ExecutePolicy 分发。

4. 打出一次带攻击上下文的 execute

在权威端对目标 Apply 第 3 步的瞬时 GE。Apply 之前用 UGCS_CombatFunctionLibrary 把攻击定义句柄写入 Effect Context(Set Attack Definition Handle 或 AddAttackHandleToGameplayEffectSpec)。

本篇可以用调试键、关卡脚本或一张只 Apply GE 的测试 Ability。不必先接 Trace 或子弹。命中检测通了但没有 Result,先回到本篇,不要先改通道或动画。

预期结果

权威端 PIE 后,目标 Shared 段能看到 Combat Flow 实例,Combat 段能看到刚才放的 Processor。Apply 一次带攻击句柄的瞬时 GE 后,Attack Result 段出现最近一条结果;LastProcessedAttackResult 能读到同一条。Default Processor 的 Event 或 Cue 各一次。

验证

  1. Gameplay Debugger 的 Combat 分类:Shared 段 Combat Flow 不是 None;Combat 段 Processor 列表非空。
  2. Apply 后 Attack Result 段有最近结果,并能看到攻击定义句柄。
  3. 对 Effect Context 调用 Get Attack Definition Handle,能读回本篇填的行。
  4. LogGCS_Combat 提到 Verbose,能看到结算。缺 Flow 时注册会打 Error。
  5. 多人 PIE 先看服务器窗口是否出现 Result。本篇不要用客户端特效证明成功。

常见失败

现象

先查

Combat Flow 一直是 None

CombatFlowClass 是否为空,或填了抽象基类

AttributeSet 改了,Flow 事件没进

目标是否有 AttributeSystem;AttributeSet 是否经 EventBridge 转发;绑定的是不是 OnPostGameplayEffectExecute

Flow 事件进了,容器仍空

是否覆写了 HandleGameplayEffectExecute 并调用 RegisterAttackResult

注册被拒绝

是否在非权威端、且 Context 不是预测上下文

GE 应用了但没有 PostExecute

Effect 是否瞬时且改了 Base Value;Duration 修饰不会进这条回调

有 Result,没有 Event / Cue

Processor 是否拖进了这个 Flow 子类;bEditorDebugEnabled 是否被关掉;Event/Cue 标签是否为空

治疗或回蓝也进了 Attack Result

项目没有按攻击定义句柄过滤。这是项目规则,不是插件默认行为

加了 Death Processor 角色没死

原生实现为空,本篇不要靠它验证闭环

下一步

容器里能看到结果之后,再按 做一次近战攻击 或 做一次远程攻击 接命中窗口。要改 Processor 策略或连击钩子,进入 处理器与战斗钩子。