阵型与 Movement Intent 扩展点

GAIS_Cover
YuewuDev

作者

YuewuDev

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

目录

阵型与 Movement Intent 扩展点

阵型扩展的核心边界是:FormationDefinition 改“阵型资产能表达什么”,FormationComponent 改“这些槽位在运行时如何投射、刷新和广播”,MovementIntentDriver 改“移动建议如何进入项目移动系统”。不要把小队角色、命令执行或移动组件实现硬塞进阵型资产。

相关文档:阵型空间与导航自适应见 阵型系统,Movement Intent 的小队职责见 小队系统。字段见 阵型、槽位与导航参数 与 小队、角色与单位参数,接入流程见 接入 Movement Intent 到移动系统,StateTree 临时 Modifier 见 用 StateTree 临时修改 Movement Intent。

UGAIS_FormationDefinition

扩展点

能改变什么

边界

CanExecute

阵型当前是否允许被选择。

只决定可用性,不应直接切换小队行为或下发命令。

HasDirection

阵型是否使用整体朝向,还是让槽位方向更重要。

不应在这里处理具体移动朝向写入。

CalculateOffsets

程序化生成或重建槽位定义。

必须输出稳定 SlotId 和可解释 SlotTags。

SetSlotDefinitions

从工具、生成器或编辑流程写入槽位定义。

不要在运行时把 SlotId 当临时数组下标重排。

CalculateOffsets 适合做圆形、扇形、楔形、随机散点等程序化阵型,但它仍然应该产出可调试的数据。长期项目里,稳定 SlotId 和 SlotTags 比“看起来排得对”更重要,因为小队分配、Unit 镜像、诊断和保存引用都依赖它们。

UGAIS_FormationComponent

FormationComponent 适合扩展运行时空间行为,而不是改小队组织规则。

扩展点

能改变什么

边界

ProjectSlotsToNavigation

在权威端自定义槽位如何投射到项目导航系统。

保持输出仍是槽位 LocationOffset / world location,不要直接驱动单位移动,也不要在客户端建第二份槽位真源。

OnFormationChanged

阵型切换后的项目侧响应。

可以做表现、日志、额外缓存,不应绕过 ready contract。

AddAvailableFormation / AddAvailableFormations

运行时开放新的阵型。

只能在服务端改;客户端侧选择应走请求或项目 RPC。

SetCurrentFormationByTraitQuery

按 FormationTraits 选择阵型。

Query 命中规则取决于 AvailableFormations 顺序和 Traits 配置。

ServerSetCurrentFormation / ServerSetCurrentFormationByTraitQuery

允许 owning client 请求服务端切换阵型。

只解决网络请求路径;项目仍应在服务端校验玩家是否可以切换到该阵型。

如果项目使用非标准 NavMesh、分层导航、飞行单位、船只或大型载具,可以覆写 ProjectSlotsToNavigation 或自定义 FormationComponent 子类,把槽位投射到项目自己的空间系统。但输出仍应保持“槽位世界结果”,让小队和 Movement Intent 不需要知道投射细节。

IGAIS_FormationSlotPreviewerInterface

Slot Previewer 用于显示槽位的运行时位置与朝向。IGAIS_FormationSlotPreviewerInterface 当前是标记接口:FormationComponent 负责生成预览 Actor、附着到阵型宿主并刷新变换,不会通过该接口传入占用状态、SlotTags 或评分诊断。

适合扩展的场景:

  • 用项目自己的网格、材质或图标显示槽位位置与朝向。
  • 区分不同 FormationComponent 子类或不同预览 Actor Class 的视觉风格。
  • 若项目确实需要显示 SlotTags、占用或导航失败状态,在项目侧查询 QuerySlots、FindSlotRuntimeView 或小队诊断数据,再建立额外的数据绑定;不要把这些状态假定为标记接口的内置输入。

UGAIS_UnitMovementIntentDriver

UGAIS_MovementIntentModifier 改的是“最终 Intent 生成前的 draft”,UGAIS_UnitMovementIntentDriver 改的是“最终 Intent 如何进入移动后端”。两者不要互相替代:Modifier 不直接移动单位,Driver 不重新计算阵型槽位或角色。

UGAIS_MovementIntentModifier

Modifier 通过 UGAIS_MovementIntentModifierSet 组织成有序集合,可以作为共享 DataAsset,也可以在 StateTree Task 中用 Inline Set。ModifyMovementIntent 接收只读上下文和可写 draft,适合改写 MovePolicy、DriverPolicy、SpeedMultiplier、DesiredSpeedOverride、PredictionVelocity 或 MovementIntentTags。

保持它纯粹非常重要:不要在 Modifier 回调里变更 roster、formation、commands、abilities、movement components 或 Modifier 绑定本身。运行时会用稳定性检查防止回调过程中破坏解析来源。

UGAIS_UnitMovementIntentDriver

UGAIS_UnitMovementIntentDriver 把小队生成的 Movement Intent 应用到项目移动系统。内置 UGAIS_UnitMovementIntentDriver_CharacterMovement 面向 ACharacter + CharacterMovement,支持写入速度和可选朝向。

Driver 有 ActivateMovementIntent、ApplyMovementIntent、ReleaseMovementIntent 三段。激活拒绝时不会进入 active driver 状态;Apply 可能每次刷新后持续调用;Intent 无效、DriverPolicy 暂停、Unit 离队或小队失效时会 Release。自定义 Driver 应让服务端维护可复制的移动真源,不要在每个客户端各自应用一份可以分歧的 Movement Intent。

项目已有 GMS、Mover、Mass、Root Motion、网络同步移动或自定义移动组件时,应新建 Driver 做胶水:

扩展方向

Driver 应该做

Driver 不应该做

CharacterMovement

写入 MaxWalkSpeed、朝向或移动请求。

决定单位是否仍属于小队。

GMS / 自定义移动

把 DesiredLocation、DesiredSpeed、bShouldMove 转成项目移动意图。

重新计算阵型槽位。

动画驱动移动

把 ResponseRatio、SlotTags 转成动画层或移动状态输入。

直接修改 SquadComponent 成员真源。

内置 CharacterMovement Driver 会记录原始 MaxWalkSpeed 和旋转控制状态;释放时只在当前值仍像是由它写入时恢复,避免覆盖项目后来接管的控制。Movement Intent 是 GAIS 给出的移动建议,不是对项目移动系统的所有权声明。