总览
Mass 移动链路最好拆成四层:行为层决定想去哪,导航层给出路径或车道,转向/避障层把路径转成期望速度和力,应用层把结果写回 Transform、Velocity 或外部 Actor。UE5.8 的 MassMovement、MassNavigation、MassZoneGraphNavigation、MassNavMeshNavigation 和 MassCrowd 都在围绕这个分层工作。
FMassDesiredMovementFragment 是重要中间结果:它保存 DesiredVelocity、DesiredFacing 和 DesiredMaxSpeedOverride。源码注释说明它是所有影响移动的 Processor 的输出,也是移动系统、Mover、动画等系统的输入。
源码依据
MassMovementFragments.h 定义 FMassVelocityFragment、FMassDesiredMovementFragment、FMassForceFragment、FMassCodeDrivenMovementTag、FMassCustomMovementTag 和 FMassMovementParameters。MassMovementTrait.h 提供 UMassMovementTrait,负责把移动参数加进模板。MassZoneGraphNavigationFragments.h 包含 FMassZoneGraphLaneLocationFragment、FMassZoneGraphCachedLaneFragment、FMassZoneGraphShortPathFragment 等路网数据。MassAI 的 Navigation 模块还提供 Steering、Avoidance、SmoothOrientation 相关 Fragment 和 Processor。
架构分析
不要让一个 Processor 同时寻路、避障、写位置。这样一旦实体穿墙或抖动,很难判断是路径错、速度错、避障错还是表现同步错。更好的拆法是:StateTree 或决策 Processor 写目标;ZoneGraph/NavMesh Processor 写路径片段;Steering Processor 写 FMassDesiredMovementFragment;Avoidance Processor 写力或修正期望速度;Apply Movement Processor 最后写 Transform 和 Velocity。
Code-driven 和 Actor-driven 也要区分。FMassCodeDrivenMovementTag 表示 Mass 直接控制速度;如果近处实体切成 Actor,并由 CharacterMovement 或 Mover 控制位置,就要把 Mass 的 DesiredMovement 传给 Actor,再从 Actor 回写位置,避免双写 Transform。
使用案例
一个沿 ZoneGraph 行走的顾客可以这样配置:
| Trait | 作用 |
|---|---|
| Transform | 保存世界位置 |
| Movement | 添加 Velocity、DesiredMovement、MovementParameters |
| ZoneGraph Navigation | 保存车道、短路径和 Lane Filter |
| Steering / Avoidance | 把路径变成速度并处理邻近避让 |
| Representation | 按 LOD 表现为 Actor、Skinned 或 ISM |
| StateTree | 决定下一个目的地或 SmartObject |
自定义移动意图 Processor 示例:
Desired[Index].DesiredVelocity = Direction * MovementParams.DefaultDesiredSpeed;
Desired[Index].DesiredFacing = Direction.ToOrientationQuat();
Desired[Index].DesiredMaxSpeedOverride = MovementParams.MaxSpeed;
这里不要直接写 Transform。让后续移动处理器统一限制加速度、平滑高度和处理朝向。
项目落地
原型阶段建议从 ZoneGraph 做人群和交通路网,因为它能表达车道、方向、标签过滤和区域连接。开放场景可以用 NavMesh Navigation 找可达点和路径,再结合 Avoidance。无论哪种方式,都要给美术和关卡一个“可视化检查”流程:路网是否断裂、Lane Tag 是否匹配、Spawn 点是否落在可导航区域、实体半径是否大于通道宽度。
常见坑
不要把目标点每帧随机重选,否则实体会来回抖。不要让多个 Processor 同时写 FMassDesiredMovementFragment 而没有顺序约定。不要忽略单位,UE 移动参数通常是 cm/s 和 cm/s²。不要在远处实体上仍然跑高频避障,低 LOD 可以降低 Tick 或只沿路径推进。
源码路径索引
MassMovement/Public/MassMovementFragments.hMassMovement/Public/Movement/MassMovementTrait.hMassAI/Source/MassZoneGraphNavigation/Public/MassZoneGraphNavigationFragments.hMassAI/Source/MassNavigation/Public/Steering/MassSteeringFragments.h