角色移动组件与 Mover
Character Movement Component & Mover
角色移动组件 (CMC) 用「客户端预测 + 服务器校验 + 纠正后重放」实现联网移动:自主代理先在本地移动并把操作存起来,用 ServerMove RPC 发给服务器重演,位置不符时服务器用 ClientAdjustPosition 纠正,客户端再按保存的操作重放;模拟代理只应用复制下来的移动并做平滑。实验性插件 Mover 计划接替 CMC,改用共享时间线、回滚与重模拟的模型,并且更模块化。
CMC 每帧做什么
CMC 在 TickComponent 中调用 PerformMovement,按当前移动模式和玩家输入计算加速度,然后在世界中实际移动角色:施加冲量、力和重力等外部物理;计算动画根运动 (root motion) 和根运动源;再通过 StartNewPhysics 选择对应移动模式的 Phys* 函数计算速度与加速度。如果本帧移动模式改变(例如开始下落),Phys* 会再次调用 StartNewPhysics,以新模式继续移动。单机游戏中每帧直接调用 PerformMovement;联网时由服务器和客户端各自的专用函数调用。(Understanding Networked Movement in the Character Movement Component for Unreal Engine)
三种网络角色与一次完整往返
| 角色 | 所在机器 | 做什么 |
|---|---|---|
| 自主代理 (Autonomous Proxy) | 拥有该角色的客户端 | 本地预测移动,记录并发送操作 |
| 权威 (Authority) | 服务器 | 重演客户端的操作,决定是否纠正 |
| 模拟代理 (Simulated Proxy) | 其他客户端 | 直接应用复制下来的移动并平滑 |
(Understanding Networked Movement in the Character Movement Component for Unreal Engine;角色的基本概念见 网络复制与 RPC)
sequenceDiagram
participant C as 自主代理(拥有者客户端)
participant S as 服务器(权威)
participant O as 模拟代理(其他客户端)
C->>C: PerformMovement 本地移动,生成 FSavedMove_Character 并存入 SavedMoves
C->>S: 合并相似操作后,用 ServerMove RPC 发送精简数据
S->>S: 用 PerformMovement 重演,比较结束位置
alt 位置不符
S->>C: ClientAdjustPosition 纠正
C->>C: 采用服务器状态,用 SavedMoves 重放之后的操作
end
S->>O: 复制 ReplicatedMovement(位置、旋转、状态)
O->>O: 直接应用 + 网络平滑上图对应官方的 9 步流程:客户端先移动、存档、发送;服务器重演并比对,不符就纠正;客户端收到纠正后从服务器给的位置重放尚未确认的操作;同时服务器把结果复制给其他客户端的模拟代理。(Understanding Networked Movement in the Character Movement Component for Unreal Engine)这正是经典的「客户端预测 + 服务器和解」模型。
- 节省带宽:缓冲区里相似的操作会合并成一个
FSavedMove_Character再发送。纠正太频繁既占带宽,又会让客户端频繁重放大量操作,所以服务器会先用WithinUpdateDelayBounds检查距上次是否已过了最短间隔,再决定是否需要纠正。(Understanding Networked Movement in the Character Movement Component for Unreal Engine) - 客户端的预测数据在
FNetworkPredictionData_Client_Character中(时间戳、已保存/待发送的操作、纠正信息、平滑参数);服务器端对应FNetworkPredictionData_Server_Character。复杂度主要在自主代理与服务器之间的预测和纠正,模拟代理只需跟上服务器给的状态。(Understanding Networked Movement in the Character Movement Component for Unreal Engine)
Mover:下一代移动(实验性)
Mover 插件支持模块化的 Actor 移动,并通过 Network Prediction 插件或 Chaos 网络物理实现回滚联网;目标是让玩法开发者不需要网络专业知识也能做移动。Epic 打算让它最终取代 CMC,但目前仍是实验性功能,API 和数据格式可能变化;即便 Mover 可用于生产,CMC 在可预见的未来仍会继续支持。(Mover in Unreal Engine)
| Mover | CMC | |
|---|---|---|
| 结构 | 模块化、不限 Actor 类型、支持更多形状 | 单体、必须是 ACharacter、只能用胶囊体 |
| 回滚 | 统一回滚 | 各自独立回滚 |
| 纠正 | 客户端判断 | 服务器判断 |
| 状态 | 受保护,不能从外部直接改 | 可直接访问 |
| 节奏 | 服务器驱动统一的时间线 | 客户端按自己的帧率发 RPC |
| 成熟度 | 尚未经过大量验证;支持网络物理 | 已在大量项目中发售验证;物理交互有限 |
(Comparing Mover and Character Movement Component in Unreal Engine)
复制模型差异:CMC 由拥有者客户端按自己的帧率发送「输入 + 状态」,服务器立即执行同样的移动并回复确认或纠正。Mover + Network Prediction 中,服务器和客户端在共享时间线上模拟,客户端预测性地领先服务器一小段时间,只发送某个模拟时间段的输入;服务器把输入缓冲到对应时刻再执行,然后把状态广播给所有客户端,由客户端决定是否回滚并重新模拟。(Comparing Mover and Character Movement Component in Unreal Engine)
Mover 的概念:MoverComponent 管理移动并提供查询与影响移动的 API;移动模式 (Movement Mode) 同一时刻只有一个处于激活状态;叠加移动 (Layered Moves) 是临时的附加运动(排斥力、追踪力、根运动等),可以同时存在多个、跨模式保留,类似 CMC 的 Root Motion Source;转换 (Transitions) 判断是否切换模式;移动修饰器 (Movement Modifiers) 只调参数不产生运动,例如下蹲;瞬时效果 (Instant Effects) 用于传送、强制速度等。导航通过 NavMoverComponent 和 NavWalking 模式实现,但 RVO 避障尚不支持。(Mover Features and Concepts in Unreal Engine,导航见 AI 感知、EQS 与导航)
取舍
- 现在要发售的项目:CMC 经过大量项目验证;自定义移动要同时处理好保存操作的数据和纠正逻辑,这部分复杂度在官方流程里已经可以看出来。
- Mover 的坑:状态不能从外部直接修改(例如没有可以直接设置的速度属性),只能通过模式、瞬时效果等在下一个模拟 tick 生效;玩家输入必须先合并成一条该 tick 的输入命令。Mover 也不对输入做假设,把输入转成移动模拟输入的工作要由项目自己完成(输入系统见 增强输入)。(Comparing Mover and Character Movement Component in Unreal Engine)
出处
- Understanding Networked Movement in the Character Movement Component for Unreal Engine UE 5.8 文档
- Movement Components in Unreal Engine UE 5.8 文档
- Mover in Unreal Engine UE 5.8 文档(实验性功能)
- Mover Features and Concepts in Unreal Engine UE 5.8 文档(实验性功能)
- Comparing Mover and Character Movement Component in Unreal Engine UE 5.8 文档(实验性功能)