UE5 物理设置实战清单:异步物理、子步与排查顺序
UE5 物理设置实战清单:异步物理、子步与排查顺序
这篇整理一个 ARPG 项目(PS5 主机 + Windows 开发,UE5.4 Chaos 后端)在 DefaultEngine.ini 里对物理的全套配置——不是逐字段翻译文档,而是把**「为什么这么调」和「踩过的坑」**写清楚,下次遇到「ragdoll 飘」「瓶子落地慢」「ragdoll 一接触就嗖飞」这类问题能直接对照排查。
1. 核心物理参数 [/Script/Engine.PhysicsSettings]
1.1 重力与运动学基础
| 配置项 | 推荐值 | 说明 |
|---|---|---|
DefaultGravityZ | -980.0 | 默认重力(cm/s²,向下),相当于地球 1g |
DefaultTerminalVelocity | 4000.0 | 自由落体封顶,防止数值爆炸 |
DefaultFluidFriction | 0.3 | 水 / 流体默认摩擦 |
MaxAngularVelocity | 7200.0 | 单刚体最大角速度(度/秒)。从默认 3600(10 rev/s)抬到 7200(20 rev/s),让 ragdoll 被击中时保留更多旋转动量 |
MaxDepenetrationVelocity | 750.0 | 穿透解算时的最大反推速度(cm/s)。不能设为 0(无限反推)——会把穿透刚体瞬间弹飞,典型表现是 ragdoll 一接触就「嗖」飞出场景。500 是稳妥起点,为改善 ragdoll 落地「软陷」可放到 750,仍远离失效域 |
BounceThresholdVelocity | 50.0 | 相对速度低于此阈值时不计入回弹。从 200(2m/s)降到 50(0.5m/s),让 ragdoll 落地的小冲击能正常传递 |
FrictionCombineMode | Average | 两物体摩擦取均值 |
RestitutionCombineMode | Average | 两物体回弹取均值 |
1.2 接触 / 稳定性参数
| 配置项 | 推荐值 | 说明 |
|---|---|---|
ContactOffsetMultiplier | 0.01 | 接触偏移缩放系数(按碰撞体尺寸的 1%) |
MinContactOffset / MaxContactOffset | 0.0001 / 1.0 | 接触偏移上下限(cm) |
bEnableStabilization | True | 开启接触稳定化,减轻堆叠抖动 |
bEnablePCM | True | 持久化接触流形,提升接触质量 |
bDefaultHasComplexCollision | True | 默认拥有复杂碰撞(每三角面) |
DefaultShapeComplexity | CTF_UseSimpleAndComplex | Query 时同时用简单和复杂碰撞 |
TriangleMeshTriangleMinAreaThreshold | 5.0 | 三角面最小面积阈值(cm²),剔除退化三角形 |
1.3 CCD / 精度 / 休眠
| 配置项 | 推荐值 | 说明 |
|---|---|---|
bDisableCCD | False | 允许连续碰撞检测,高速物体(弹道、抛射)需要 |
RagdollAggregateThreshold | 4 | Ragdoll 聚合阈值,≥4 个刚体打包为一个 aggregate 提升求解效率 |
bSimulateSkeletalMeshOnDedicatedServer | True | 专用服务器也模拟骨骼网格物理(布娃娃同步需要) |
bWarnMissingLocks | True | 缺线程锁时打印警告 |
SimulateScratchMemorySize | 262144 | 物理模拟 scratch memory(256 KB) |
1.4 时间步进与异步物理(关键 ⚠️)
| 配置项 | 推荐值 | 说明 |
|---|---|---|
MaxPhysicsDeltaTime | 0.1 | 单次 tick 最大物理 DT(秒),兜底防止卡顿后暴冲 |
bSubstepping | True | 同步路径启用子步 |
bSubsteppingAsync | True | 异步路径启用子步,必须为 True |
MaxSubstepDeltaTime | 0.008333 | 单个子步最大 DT(120 Hz) |
MaxSubsteps | 6 | 每游戏帧最多推进 6 个子步 |
bTickPhysicsAsync | True | 启用异步物理线程,必须为 True |
AsyncFixedTimeStepSize | 0.016667 | 异步物理固定时间步(60 Hz) |
🚨 红框约束
bTickPhysicsAsync=True 与 bSubsteppingAsync=True 必须同时为 True。不要因为「ragdoll 飘」「瓶子落地慢」就建议关掉 async。两个反例都从实际 trace 里复现过:
- 关
bTickPhysicsAsync→ GT 被 Chaos 物理阻塞 ~55 ms(纯WaitForTasks),几十个骨骼物理体在 GT 同步调度,帧率直接掉到 11 FPS。 - 开 async 但关
bSubsteppingAsync→ UE 5.4 Chaos 的坑:每游戏帧只推进 1 步AsyncFixedTimeStepSize,帧时间 >AsyncFixedTimeStepSize时物理时间轴慢于墙钟(实测 91ms 帧 → 物理时间 16.67ms,5.46× 慢动作)。表现为「瓶子落地慢 5 倍」「ragdoll 轻飘飘」。 - 两者都开 → 帧时间 89→39 ms,
PhysicsParallelFor29→6 ms/帧,GT 阻塞消失,瓶颈干净转移到 GPU。
如果用户抱怨物理手感问题,先排查的不是这些 ini 项,而是:
- PhysicsAsset 的 Damping / Mass 设置
- PhysicalMaterial 的 Density
- Chaos Solver 迭代数(
p.Chaos.Solver.PositionIterations/VelocityIterations)
配套调整
启用 bTickPhysicsAsync=True 后,async 路径走 AsyncFixedTimeStepSize 固定步长,对下列几项敏感——必须一起调整:
| 配置项 | 旧值 | 新值 | 与 async 的关联 |
|---|---|---|---|
MaxSubsteps | 3 | 6 | async 每帧最多推进 MaxSubsteps × AsyncFixedTimeStepSize 的物理时间。3 × 16.67ms = 50ms 只能兜住 20fps,帧时间再长就进入慢动作;改 6 后兜到 100ms / ~10fps,覆盖 worst-case |
MaxPhysicsDeltaTime | 0.0333 | 0.1 | 引擎吃掉 dt 的总封顶。必须与 MaxSubsteps × MaxSubstepDeltaTime = 6 × 16.67 = 100ms 对齐,否则 MaxSubsteps 抬高也无效 |
bEnableStabilization | False | True | async + 多子步推进使 ragdoll 堆叠接触在不同子步里反复求解,配合 PCM 降低触地颤动 |
MaxDepenetrationVelocity | 0(不限) | 500 起步,可放到 750 | async 高频求解下,无限反推速度会把穿透刚体瞬间弹飞 |
1.5 Chaos 线程模型
| 配置项 | 推荐值 | 说明 |
|---|---|---|
ChaosSettings.DefaultThreadingModel | TaskGraph | 用 TaskGraph 调度(非专用线程) |
ChaosSettings.DedicatedThreadTickMode | VariableCappedWithTarget | 未启用专用线程时的 fallback |
ChaosSettings.DedicatedThreadBufferMode | Double | 双缓冲 |
1.6 网络物理错误修正 PhysicErrorCorrection
用于网络同步下的刚体位置插值 / 外推。重点字段:
| 字段 | 推荐值 | 说明 |
|---|---|---|
PingExtrapolation | 0.1 | ping 外推系数 |
PingLimit | 100.0 | ping 上限(ms) |
MaxLinearHardSnapDistance | 400.0 | 超过此距离直接硬 snap(cm) |
PositionLerp | 0.0 | 不做位置插值(硬 snap 策略) |
AngleLerp | 0.4 | 角度 40% 插值 |
ErrorAccumulationSeconds | 0.5 | 误差累积时间窗 |
1.7 广相 DefaultBroadphaseSettings
bUseMBPOnClient=False
bUseMBPOnServer=False
MBPNumSubdivs=2
默认不启用 MBP(Multi-Box Pruning),使用 Chaos 默认的 SAP 广相。开放世界 / 极大场景再考虑 MBP。
2. 物理表面 PhysicalSurfaces
定义全部使用到的 SurfaceType(覆盖 SurfaceType1~33)。每种表面在以下系统中被消费:
- 选择击中 VFX/SFX;
- 脚步声根据地表材质触发对应 Wwise event;
- 战斗打击判定根据 surface 切换击中反馈。
常用表面分类示例:硬地面(Asphalt / Concrete / Rock)、软地面(Dirt / Mud / Grass / Sand / Snow)、布料 / 肉(Fabric / Flesh / BloodOverkill)、金属 / 玻璃 / 木 / 塑料、特殊(EnergyShield / Lava / Oil / Ice)等。
UPhysicalMaterial 的 SurfaceType 枚举必须从此列表中选。
3. 碰撞配置 [/Script/Engine.CollisionProfile]
项目通常在 UE 默认基础上大量扩展,分为 Profile(剖面)、TraceChannel(追踪通道)、ObjectChannel(物体通道)、重定向四类。
3.1 Trace Channel 命名套路
通过 +DefaultChannelResponses 定义,bTraceType=True 为 TraceChannel,False 为 ObjectChannel。
| 索引 | 用途示例 |
|---|---|
GameTraceChannel1 | CombatTrace —— 战斗命中检测 |
GameTraceChannel2 | Player —— 玩家 Capsule 物体通道 |
GameTraceChannel3 | InvisibleWall —— 隐形墙 |
GameTraceChannel4 | Accessory —— 配件 / 挂件 |
GameTraceChannel5 | Trigger —— 触发器物体 |
GameTraceChannel14 | FootIKGroundTrace —— 脚 IK 向下追踪 |
GameTraceChannel15 | FluidTrace —— 流体表面追踪 |
3.2 Profile(碰撞剖面)
引擎默认剖面被 -Profiles 移除后,由 +Profiles 重新定义。按用途分类,常见组:
- 角色/Pawn 类:Pawn / Player / Spectator / CharacterMesh / Ragdoll / Corpse
- 物理 Actor 类:PhysicsActor / Destructible / LootItem
- 环境墙/阻挡:BlockAll / BlockAllDynamic / BlockAllExceptCamera / InvisibleWall
- 触发器 / Overlap:Trigger / OverlapAll / OverlapOnlyPawn
- 飞行体 / 武器:Flight / VehicleHitShape / Vehicle
- 杂物 / 特殊:Trash01/Trash02 / WaterBodyCollision / EQS_OnlyBlockWorld / UI
3.3 重定向(兼容旧资产)
ProfileRedirects(剖面名重定向)
| 旧名 | 新名 |
|---|---|
| BlockingVolume | InvisibleWall |
| InterpActor | IgnoreOnlyPawn |
| StaticMeshComponent | BlockAllDynamic |
| SkeletalMeshActor | PhysicsActor |
| InvisibleActor | InvisibleWallDynamic |
CollisionChannelRedirects(通道名重定向)
| 旧名 | 新名 |
|---|---|
| Static | WorldStatic |
| Dynamic | WorldDynamic |
| VehicleMovement | Vehicle |
| PawnMovement | Pawn |
4. PhysicsControlComponent 重定向到预算化版本
利用 ClassRedirects 把引擎原生 UPhysicsControlComponent 全局替换成接入 Significance/Budget 体系的项目子类(如 UPhysicsControlComponentBudgeted):
+ClassRedirects=(OldName="/Script/PhysicsControl.PhysicsControlComponent",
NewName="/Script/<Game>.PhysicsControlComponentBudgeted")
所有旧资产引用 PhysicsControlComponent 的资产在加载时会自动转成预算化版本,无需手动迁移。Significance 预算 CVar 示例:
- 角色预算 5 ms
- Mass NPC 预算 1 ms
NotTickLevel=4:不 tick 级别NotTickNonRenderTime=10:不渲染持续 10 秒后停 tick
5. 排查检查单
遇到物理问题时,按以下顺序排查,不要盲目改 ini:
- 看日志:过滤
LogPhysics、LogChaos、LogPhysicsCore、玩法相关日志通道。 - 看追踪报告:Unreal Insights trace 是帧率 / 物理 / 渲染问题的事实来源。
- 检查资产:
- PhysicsAsset 的 Mass(实际 kg)、Linear/Angular Damping、MaxAngularVelocity 覆写
- PhysicalMaterial 的 Density / Friction / Restitution
- 对应 Profile 的通道响应,尤其是被
EditProfiles追加过的项
- 检查 Solver:
p.Chaos.Solver.PositionIterations、p.Chaos.Solver.VelocityIterations- 默认 8/1;ARPG 项目常调到 10/2 让 ragdoll 接触 / 关节求解更刚。再往上加(如 12/3)会显著推高物理 CPU,必须先有 trace 证据。
- 最后才看全局 ini:要改
[/Script/Engine.PhysicsSettings]任何一项前,先准备 trace 对比。bTickPhysicsAsync与bSubsteppingAsync不要动。
6. 修改 ini 的纪律
把改动用注释包起来(ini 用
;),方便后续 review / blame:; --- physics async tweak begin --- MaxSubsteps=6 MaxPhysicsDeltaTime=0.100000 ; --- physics async tweak end ---提交前本地跑一次包含 ragdoll + 飞行物 + 载具爆破的场景冒烟。
性能关键项需附 trace 对比报告。
7. 经验
bTickPhysicsAsync+bSubsteppingAsync是「同生死」的开关,单开 async 不开子步会触发 UE 5.4 Chaos 的「物理慢动作」坑。MaxSubsteps × MaxSubstepDeltaTime必须 ≥MaxPhysicsDeltaTime,否则MaxSubsteps抬高没用。MaxDepenetrationVelocity = 0(无限反推)是 ragdoll 弹飞的常见配方,450–750 是稳妥区间。- 物理问题的第一排查方向永远是 PhysicsAsset / PhysicalMaterial / Solver 迭代数,不是全局 ini。改全局之前先收 trace 证据。