CharacterMovement
CharacterMovement
性能优化
simulate step
所谓的step,就是当一帧时间过长时候(帧率低或者卡顿的时候),移动组件会把这个时间拆分成小的step,每一个step完整跑一段移动模拟,每一段移动模拟至少产生三次物理碰撞检测(sweep),step up,step forward, step down。
优化移动模拟次数。这次有两个值控制:
- MaxSimulationIterations,决定一次移动组件update最多少产生多少次模拟,定义最大子步数
- MaxSimulationTimeStep,每一次模拟最大时长,限制每个子步的时间间隔
按角色重要性动态调整参数
我们把这两个值接入到逻辑LOD管理器,根据是否屏幕可视和距离决定跌代次数,不见时把MaxSimulationIterations改为1,太远的时候MaxSimulationIterations改为2,目前看来,没发现有什么问题。
利用UE的SignificanceManager系统,可根据角色与玩家的距离或重要性分级设置参数:
- 近处/关键角色(如玩家自身、Boss):保留默认值(
MaxSimulationIterations=8,MaxSimulationTimeStep=0.0167s),确保移动精度和碰撞响应的及时性。例如,玩家角色在爬墙或跳跃时,足够的迭代次数能避免穿模或卡顿。 - 远处/次要角色(如背景NPC):降低迭代次数(如
MaxSimulationIterations=4)并增大时间步长(如MaxSimulationTimeStep=0.033s)。这会减少CPU占用,但可能导致移动细节简化(如布料摆动幅度减小)。
性能与精度的权衡技巧
限制最大迭代次数的边际效益:
超过16次迭代后,精度提升有限但性能成本显著增加。建议通过UE Profiler监控CharacterMovement模块的耗时,找到平衡点。例如,在移动端将迭代次数控制在4-6次,避免帧率波动。时间步长与帧率的匹配:
MaxSimulationTimeStep应与目标帧率对应(如30FPS对应0.033s,60FPS对应0.0167s)。若设置过大(如>0.05s),可能导致角色移动“跳跃”;过小(如<0.01s)则会增加子步计算次数。例如,在低帧率场景(如20FPS)下,可将时间步长设为0.05s,减少CPU压力。网络同步场景的特殊处理:
在多人游戏中,服务器需对所有角色进行物理模拟,建议统一降低MaxSimulationIterations(如设为6),并通过ClientAdjustPosition函数修正客户端位置偏差,避免因参数不一致导致的同步问题。
常见问题
| 问题 | 原因 | 优化方案 |
|---|---|---|
| 角色穿模或卡在地形 | 迭代次数不足,碰撞检测不充分 | 提高MaxSimulationIterations至8-10,或减小MaxSimulationTimeStep至0.01s |
| 移动端帧率过低 | 物理计算占用CPU过高 | 降低迭代次数至4-5,增大时间步长至0.033s,关闭次要角色的物理模拟 |
| 跳跃顶点动画卡顿 | 时间步长过大,速度计算精度不足 | 启用CharacterMovementCVars::ForceJumpPeakSubstep,细分顶点时间步 |
update骨骼和子transform
当移动组件移动时,更新当前actor下所有的transform,比如骨骼网格体的物理资产,骨骼socket挂接的特效等。这里消耗不低,物理是特效,如果量大的话,会带来一系列的性能,比如发送transform信息到render thread,更新gpu scene.
overlap事件
当移动组件完成后,会在最后时机,把当前actor下所有会产生overlap事件的component,一个一个递归update,减少没必要的overlap事件,我们优化的时候,大部分的overlap事件都是无用的,只保留capsule就够了。
check floor
引擎默认是每帧都检测地面的,可以关闭,只有移动的时候才检测地面,这里可以减少大量怪物在待机状态下每帧都进行地面的检测消耗,但是会带来一个负作用就是,如果角色站在一个破坏物上,破坏物被打碎,角色仍在空中的情况,因为角色没有动。我们把check floor这个字段接入到逻辑LOD管理器,把远处的check floor全去掉,移动组件干净了好多。
CharacterMovementComponent上的UseAccelerationForPaths性能消耗
在 Unreal Engine 5 的 CharacterMovementComponent (CMC) 中,bUseAccelerationForPaths 是一个决定 AI 路径跟随行为的关键开关。理解它的性能消耗需要从 CPU 计算开销 和 移动物理模拟 两个维度来看。
以下是关于该设置性能消耗的详细分析:
- 核心概念对比
关闭 (false - 默认路径):AI 直接修改 Velocity(速度)。路径跟随组件直接计算出下一帧应该在哪,然后硬设置速度。这是一种“瞬间达速”的模式。
开启 (true - 加速度路径):AI 修改 Acceleration(加速度)。路径跟随组件计算出期望方向,将其作为输入传给 CMC,由 CMC 经过摩擦力、转向速度(RotationRate)和最大加速度(MaxAcceleration)计算出最终速度。 - CPU 性能消耗分析
开启 bUseAccelerationForPaths 会带来更高的 CPU 瞬间开销,原因如下:
复杂的物理计算循环: 当使用加速度时,CMC 必须进入完整的 CalcVelocity 逻辑。这涉及到每帧计算摩擦力(Friction)、制动力(Braking)以及速度方向的插值。相比之下,直接设置速度几乎是瞬时完成的。
更多的子步迭代 (Sub-stepping): 为了保证物理模拟的准确性,加速度模式下更容易触发 CMC 的内部子步计算。如果在一个帧内加速度导致位移超过阈值,系统会拆分多次计算以“消除(eliminate)”穿模风险,这显著增加了 CPU 耗时。
逻辑路径分支: 在 C++ 源码中,PhysWalking 和 PhysFalling 逻辑会检查此布尔值。开启后,它会调用更多关于输入矢量(Input Vector)的过滤函数,增加了函数调用堆栈的深度。 - 移动质量与表现的权衡
虽然性能消耗更高,但它解决了以下问题:
表现力:开启后,AI 转向会更圆滑,有起步加速和停止减速的过程,看起来更像真实生物,而非平移的方块。
稳定性:直接设置速度可能会导致 AI 在导航点转折处产生剧烈的视觉抖动,而加速度模式通过物理模拟“消除(eliminate)”了这种不自然的瞬移感。 - 优化建议与最佳实践
如果你在场景中有大量的 AI(例如超过 50-100 个 NPC),请考虑以下优化方案:
群体 AI 禁用:对于远处的背景人群或简单的僵尸类 AI,建议关闭 bUseAccelerationForPaths。直接设置速度能节省大量的物理计算开销。
重要角色开启:仅为玩家附近的精英敌人或主角同伴开启此项,以保证其移动的高级感。
调整 MaxSimulationIterations: 如果你必须开启加速度,可以在 CMC 中降低 MaxSimulationIterations(默认通常为 8,建议降至 2 或 4)。这能有效限制在高负载下的物理计算递归次数。
使用性能分析工具: 使用 Unreal Insights 查看 CharacterMovementComponent::TickComponent 的耗时。如果你发现 CalcVelocity 占据了大量绿条,那么 bUseAccelerationForPaths 就是主要的优化目标。
总结
bUseAccelerationForPaths 的性能消耗明显高于直接速度控制。在处理大规模单位(Crowd)时,它是首先需要被“消除(eliminate)”或禁用的高能耗选项;但在追求高品质单人动作体验时,它是实现细腻移动表现的基础。