UE5.8 Physics Asset 与角色碰撞体

📑 目录

UE5.8 Physics Asset 与角色碰撞体

阅读前提:你已经能在 UE5.8 中导入角色骨骼网格体,并对蓝图动画有一定了解。

故事:斧头落下那一刻

战场边缘,一名持盾步兵被敌方重斧从侧面击中肩膀。骨头断裂的声音没有响,因为这只是游戏。真正在运行的是这样一段逻辑:动画系统收到受击事件, blends 权重在几帧内从全身动画切到物理驱动,肩膀处的球形碰撞体被施加一个冲量,整个身体的刚体链跟着翻滚。随后角色倒在地上,四肢按照质量分布继续滑动,直到摩擦力让它停下。

这个画面好看与否,取决于 Physics Asset 的质量。碰撞体太大,角色会隔空弹开;太小,斧头会穿过肩膀。质量分布不对,倒地后会像气球一样轻飘。约束太松,四肢会拧成麻花;约束太紧,又像一根木棍。本文把 UE5.8 中相关设置逐一拆开,看看到底哪些旋钮在控制这些细节。

Physics Asset 编辑器概览

Physics Asset(.phat)依附于 Skeletal Mesh。打开方式:在 Content Browser 中双击目标 .phat 文件,或者选中骨骼网格体后在菜单里选择 Create Physics Asset。编辑器主窗口分为视口、骨架树、细节面板和工具栏四块。工具栏里最常用的几个按钮是:

  • New Body:为选中的骨骼创建新的物理形体;
  • New Constraint:在两根骨骼之间建立物理约束;
  • Simulation:开启实时物理模拟,可以直接用鼠标推拉角色;
  • Mesh/Body/Constraint 三个显示模式切换。

下面的架构图展示了 Physics Asset 在资源栈里的位置。

flowchart TD
    mesh["骨骼网格体"]
    body["物理形体"]
    constraint["物理约束"]
    abp["动画蓝图"]
    skc["SkeletalMeshComponent"]
    world["World"]

Physics Asset 的核心数据结构是 UBodySetup,每个物理形体对应一个 FKBoxElemFKSphylElemFKSphereElem。约束则存放在 UPhysicsConstraintTemplate 里。UE5.8 在这些底层结构上做了若干缓存优化,后文会提到。

编辑器里还有两个容易被忽略的面板。Bone Tree 按骨骼层级列出所有已创建形体的骨骼,没有形体的骨骼显示为灰色。Profiles 面板可以保存多套物理配置,例如站立、骑马、攀爬时调用不同的形体集合。这套机制对骑乘系统特别有用,因为角色跨坐在坐骑上时,大腿内侧不应该再与地面碰撞。

约束基础

约束连接两根骨骼,限制它们之间的相对运动。每个约束有六个自由度,三个移动、三个旋转。角色骨骼通常锁定全部移动自由度,只保留旋转。旋转自由度的限制用 Swing 和 Twist 表示:Swing 控制骨骼在锥形范围内的摆动,Twist 控制绕自身长轴的扭转。膝盖只能前后弯曲,所以左右 Swing 限制得很小,前后 Swing 稍大,Twist 基本锁死。肩膀活动范围大,Swing 可以放到六十度以上,Twist 保留三十度左右。电机属性里的 Spring、Damping、Max Force 控制约束抵抗偏离的强弱。Spring 太硬会像焊死,太软会耷拉。调试时开启 Simulation,拖拽肢体就能直观感受这些参数。

Skeletal Mesh 的碰撞体形状

角色网格体有几十万面,直接拿来当碰撞体会让物理引擎崩溃。Physics Asset 用简化的凸包或基本几何体来近似。可选形状有三种:

  1. Sphere:适合关节末端,如拳头、脚腕;
  2. Sphyl / Capsule:最常用,躯干、大臂、小腿都适用;
  3. Box:适合扁平部位,如盾牌、腰带、胸甲。

选择形状时别只看网格贴合度,还要看转动惯量。CAPSULE 绕着长轴旋转时惯性较小,适合四肢摆动;BOX 在棱角处更容易卡住,适合装备。UE5.8 的自动形体生成器增加了 Orientation 与 DOP 选项,可以在细节面板里一键把胶囊替换成凸包,但自动结果通常需要手工微调。

下面这张流程图演示了把网格变成可用碰撞体的典型路径。

flowchart TD
    A["导入 Skeletal Mesh"] --> B{已有 Physics Asset?}
    B -->|"否"| C["自动生成默认形体"]
    B -->|"是"| D["打开编辑器"]
    C --> D
    D --> E["调整每根骨骼的形状与尺寸"]
    E --> F["设置约束限制与电机"]
    F --> G["运行 Simulation 验证"]
    G -->|"穿模/抖动"| E
    G -->|"稳定"| H["保存并进入游戏测试"]

实战建议

  • 躯干用单个胶囊覆盖胸腔与腹部即可,没有必要拆成脊椎每一节;
  • 手腕和脚踝的形体半径不要小于实际骨骼长度的一半,否则翻滚时容易穿插;
  • 头部如果戴头盔,可以额外加一个 Box 形体会话头盔,但要在蓝图中关闭它与头发的碰撞;
  • 裙子、披风、辫子等附件更适合 Cloth 或 Chaos,而不是 Physics Asset 刚体。

对于人形角色,推荐的形体分配大致如下:骨盆一个胶囊,脊柱一根,胸腔一根,头一个球,左右大臂、小臂、手掌、大腿、小腿、脚掌各一个。总计十五个左右。数量太少会丢失细节,太多会拖慢模拟。UE5.8 的自动生成器现在会按这个经验比例给出初始方案,比自己从零搭建快很多。

凸包与 DOP

当基本几何体无法贴合装备时,可以改用凸包。凸包由多个平面围成,计算量比胶囊大,但能准确表现盾牌边缘或机械臂外壳。UE5.8 提供了 DOP 选项,也就是 k-DOP 包围体,常见的有 10-DOP、18-DOP、26-DOP。DOP 数字越大,形状越接近原网格,顶点数也越多。建议只在静态装备上用高 DOP,运动频繁的肢体保持胶囊。

质量分布与质心

Physics Asset 默认会给每个形体分配质量。质量总和与分布直接决定倒地后的运动轨迹。质心位置可以用下面这个块级公式近似表示:

rCOM=imiriimi\vec{r}_{\text{COM}} = \frac{\sum_i m_i \vec{r}_i}{\sum_i m_i}

其中 mim_i 是第 ii 个形体的质量,ri\vec{r}_i 是其局部中心。UE5.8 的 Physics Asset 编辑器在视口中新增了 COM 可视化标记,选中 Show > Center of Mass 就能实时看到红点位置。一个成年男性角色的质心大概在髋骨略上方;如果质心跑到胸口,角色被击中后会像不倒翁一样快速回正,丧失真实感。

密度与质量分配

每个形体有 MassDensity 两个属性。建议用 Density 统一设置,让编辑器自动根据体积计算质量。常用密度参考:

  • 头部:约 1050 kg/m31050 \text{ kg/m}^3,接近人体密度;
  • 胸腔:约 1100 kg/m31100 \text{ kg/m}^3,包含骨骼与内脏;
  • 四肢:约 1000 kg/m31000 \text{ kg/m}^3
  • 装备:金属甲片可给到 2700 kg/m32700 \text{ kg/m}^3 以上。

总质量建议与角色设计一致。一个 1.8 米高的战士总质量 75 kg75 \text{ kg} 比较合理;如果躯干就占了 60 kg60 \text{ kg},四肢动作会显得沉重。

转动惯量 II 决定角色绕某轴旋转的难易程度。对于半径为 RR、半高为 hh 的胶囊,绕中心横轴的转动惯量近似为:

I112m(3R2+4h2)I \approx \frac{1}{12} m \left(3R^2 + 4h^2\right)

这解释了为什么把小腿做成长胶囊后,角色被绊倒时会慢半拍倒下。适当缩短胶囊长度、降低密度,可以让反应更灵敏。

质量比例的手感

质心高度还会改变受击后的旋转轴。低质心让角色倾向平移,高质心让角色倾向翻转。武侠游戏里常见的挑飞效果,本质就是把受击点选在腹部下方,再给一个向上的冲量,利用高质心产生翻转力矩。相反,盾牌猛击适合打在重心附近,让角色向后平推。

力矩 τ=r×F\vec{\tau} = \vec{r} \times \vec{F} 也受打击点位置影响。同样的冲量打在头顶与打在脚踝,产生的角加速度差别巨大。调试时可以让 Gamasense 在视口中绘制冲量方向线,观察力的作用线是否穿过质心。穿过质心产生纯平动,偏离质心产生转动。掌握这个关系后,调受击手感就有了明确方向。

物理动画混合

直接切到 Ragdoll 会有硬过渡。物理动画混合(Physics Animation Blending)让动画 Pose 与物理模拟Pose 按权重融合,既保留动画的艺术感,又增加环境互动。

实现方式有两种:

  1. 动画蓝图中的 Blend Physics Bodies:在 AnimGraph 里用 Physics Blend Weight 节点,把部分骨骼切到物理模拟;
  2. USkeletalMeshComponent::SetAllBodiesBelowPhysicsBlendWeight:在 C++ 或蓝图中按骨骼名称逐层设置混合权重。

下面的序列图展示了一个普通受击事件如何与物理系统协作。

sequenceDiagram
    participant G as Gameplay
    participant ABP as "Animation Blueprint"
    participant SK as SkeletalMeshComponent
    participant PA as "Physics Asset"
    participant Phy as Chaos

    G->>ABP: 触发受击事件
    ABP->>ABP: 计算冲击方向与强度
    ABP->>SK: 设置 Physics Blend Weight
    SK->>PA: 查询对应骨骼的形体
    PA->>Phy: 施加冲量 impulse
    Phy-->>SK: 返回模拟后的骨骼变换
    SK-->>ABP: 同步骨骼 Pose
    ABP-->>G: 通知倒地状态

混合权重的意义

混合权重 w[0,1]w \in [0,1] 可以这样理解:当 w=0w=0 时完全走动画;w=1w=1 时完全交给物理。中间状态用线性插值:

Tfinal=(1w)Tanim+wTphysT_{\text{final}} = (1-w) \cdot T_{\text{anim}} + w \cdot T_{\text{phys}}

实际操作中,不要让全身同时切到 w=1w=1。例如肩部中箭,可以把锁骨、肩胛骨、上臂的权重快速拉到 0.80.8,躯干保持 0.30.3,下半身继续走动画。这样角色会捂肩后退,而不是立刻倒地。

UE5.8 在 AnimGraph 里新增了 Physics Animation Profile 资产,可以预设多套混合曲线。不同武器类型调用不同 Profile,比如钝器重击用慢速上升的曲线,箭矢用瞬时峰值然后快速回落。

局部空间与组件空间

物理模拟可以在 Local Space 或 Component Space 中运行。Local Space 下,骨骼变换相对于父骨骼计算,适合局部受击;Component Space 下,所有骨骼相对于组件原点计算,适合全身 Ragdoll。混合时如果权重变化剧烈,建议把受击部位先切到 Component Space,让 Chaos 统一处理,等稳定后再 Blend Out 回 Local Space。这个切换节点在 5.8 中改名为 Convert to Physics Space,旧版本叫 Local to Component。名字变了,功能不变。

恢复过渡

混合不只是切过去,还要切回来。角色从 Ragdoll 恢复站立时,需要把 Physics Blend Weight 从 11 降到 00。这个过程中最好配合一个起身动画,否则会出现骨骼被物理拉回动画 Pose 的鬼畜抖动。UE5.8 的 Ragdoll Recovery 节点会自动记录 Blend Out 前的骨骼速度,并在恢复时施加反向阻尼,让过渡更稳。

Ragdoll 与受击

Ragdoll 是物理动画的极端情况:动画权重降到接近零,所有相关骨骼完全由 Chaos 驱动。最常见的触发点有两个:

  • 角色生命值归零;
  • 受到超过阈值的冲击力。

实现 Ragdoll 的蓝图调用通常是:

// 让上半身进入 Ragdoll
Mesh->SetAllBodiesBelowSimulatePhysics(FName("spine_03"), true);

// 在受击点施加冲量
Mesh->AddImpulseAtLocation(
    ImpactDirection * ImpactStrength,
    HitLocation,
    BoneName
);

注意 AddImpulseAtLocation 的冲量单位是 NsN \cdot s,也就是动量变化 Δp\Delta p。根据动量定理 FΔt=mΔvF \Delta t = m \Delta v,想让一个 75 kg75 \text{ kg} 的角色获得 2 m/s2 \text{ m/s} 的速度变化,需要施加约 150 Ns150 \text{ N}\cdot\text{s} 的冲量。

受击表现调优

  • SetAllBodiesBelowPhysicsBlendWeight 而不是一次性全开 Ragdoll,可以先让受击部位软一下;
  • 冲量施加点选在骨骼附近,而不是皮肤表面,否则距离杠杆会让效果夸张;
  • 倒地后延迟 0.3 到 0.5 秒再冻结,给布料和粒子留出反应时间;
  • 用约束的 Angular Soft Constraint 降低关节旋转速度,避免四肢甩成不自然角度。

死亡布娃娃的冻结策略

Ragdoll 倒地后如果一直模拟,会消耗 CPU。常见做法是在速度低于阈值后调用 PutRigidBodyToSleep,让刚体休眠。更激进的做法是在 5 到 10 秒后把 SkeletalMeshComponent 的 Collision Profile 切到 RagdollFrozen,同时关闭 Simulate Physics,只保留一个 Capsule Component 用于尸体阻挡。UE5.8 的 Physics State Recorder 可以把最终姿态烘焙成静态 Pose,方便后续作为尸体资源复用。

碰撞通道配置

Physics Asset 里的每个形体都要回答一个问题:它和谁碰撞?答案由 Collision Profile 决定。在编辑器中选中形体,Details 面板里找到 Collision Reponses,可以为每个通道设置 Ignore、Overlap 或 Block。

下面这张图用 graph 形式展示了 Pawn、WorldDynamic、Weapon 三个通道之间的关系。

graph LR
    A["Pawn 形体"] -->|Block| B[WorldStatic]
    A -->|Block| C[Weapon]
    A -->|Ignore| D[Camera]
    C -->|Overlap| E[Projectile]
    F[Cloth] -->|Ignore| C
    F -->|Block| B
    G["Hitbox 受击盒"] -->|Block| C

常见通道策略

  • Pawn:角色自身主碰撞体,与地形、门、墙 Block;
  • Visibility / Camera:手臂、头部通常 Ignore,避免第三人称镜头被自己的模型挡住;
  • Weapon:敌人武器单独设一个通道,只与 Pawn 的受击盒 Block;
  • Projectile:弓箭、法术用 Overlap 检测,配合 Event OnComponentBeginOverlap 处理伤害;
  • Cloth / Hair:与武器 Ignore,减少抖动。

UE5.8 新增了 Collision Snapshot 功能,可以在编辑器里录制一段模拟,事后逐帧检查哪两个形体发生了穿透。配合 Show Collision 可视化,调试效率比旧版本高很多。

自定义受击盒

很多动作游戏会在 Skeletal Mesh 上单独挂几个 Box Collision,专门用于伤害判定。这些盒子不参与物理模拟,只用于 Overlap 查询。它们与 Physics Asset 形体的关系是:前者决定打没打中,后者决定打中后怎么动。两者的尺寸不必一致。受击盒可以比实际形体大 10 到 15 厘米,给网络延迟留点余量。

性能优化

物理模拟是 CPU 开销大户。一个场景里如果同时有二十个 Ragdoll,帧率会明显下降。优化思路分三个层次:

1. 减少刚体数量

标准人体骨架动辄七八十根骨骼,但 Physics Asset 不需要每根都建形体。把相邻小骨骼合并到父骨骼,通常能把形体数量从六十压到十五到二十。例如手指可以完全不建形体,手腕处用一个稍大的胶囊带过去。

2. 降低模拟精度

在 Project Settings > Physics 里调整:

  • Max Substep Delta Time:默认 1/60 秒,Ragdoll 密集时可以放宽到 1/30;
  • Max Substeps:限制单次 tick 的最大子步数,防止复杂堆叠爆炸;
  • Solver Iteration Count:从默认 4 降到 2,对远处 NPC 的 Ragdoll 足够。

3. LOD 与距离裁剪

UE5.8 支持 Physics Asset LOD。靠近玩家的角色用高精度形体,远处的用简化版,更远处直接关闭模拟。可以在 SkeletalMeshComponent 上设置 Physics Transform Update Mode:当角色离镜头远时切到 Component Space 或完全禁用,节省骨骼更新开销。

另外,倒地角色若已静止,可以调用 PutRigidBodyToSleep 让它进入睡眠状态。刚体睡眠后不再参与循环计算,直到再次受力唤醒。这在尸堆场景里非常有效。

异步与多线程

UE5.8 的 Chaos 支持异步物理 tick。开启后,渲染线程不需要等物理计算完成,帧时间更稳定。代价是物理结果会延迟一帧,对大多数第三人称动作游戏可以接受。竞速类或对延迟敏感的项目建议保持同步模式。

性能分析命令

控制台命令 stat physics 可以查看当前物理耗时。重点关注 Total Physics TimeNum Bodies。如果发现 Ragdoll 场景里耗时飙升,先用 p.ShowCollision 1 打开碰撞可视化,检查是否有形体卡在地面里反复碰撞。另一个命令 pxvis collision 在 Chaos 下同样可用,会把所有激活的碰撞体用线框画出来。尸堆场景中常有刚体互相挤压,导致接触点数量爆炸,这时降低 Solver Iteration Count 或尽早 Sleep 是最有效的手段。

UE5.8 相关改进

相比 5.4 与 5.5,UE5.8 在 Physics Asset 和 Chaos 上做了不少可见改动:

  • Chaos Visual Debugger 集成:现在可以直接在编辑器里看到约束张力、接触点法线、质量分布热力图,不再依赖外部命令行;
  • 异步物理模拟FPhysScene 支持在独立线程 tick,渲染线程不再等待物理结果,复杂场景下帧时间更平滑;
  • 形体生成器增强:自动生成的胶囊更符合解剖比例,尤其对四足动物和机械臂有明显改善;
  • Soft Bodies 预览:虽然还不适合角色主碰撞体,但可以在 Physics Asset 编辑器里预览 Soft Bodies 对衣物的影响;
  • 物理资产重定向:把一个角色的 Physics Asset 重定向到骨架相似的新角色时,UE5.8 会基于 T-pose 自动匹配骨骼长度,减少手工对位。

下面这张图用 graph 形式总结了 UE5.8 物理管线的数据流向。

graph TD
    A["动画 Pose"] --> B{Physics Blend Weight}
    B -->|"w < 0.5"| C["动画驱动"]
    B -->|"w >= 0.5"| D["Chaos 模拟"]
    D --> E["约束求解"]
    E --> F["接触检测"]
    F --> G["输出骨骼变换"]
    G --> H["渲染与Gameplay反馈"]
    C --> H

小结

Physics Asset 是角色与环境互动的幕后导演。碰撞体形状决定能不能被正确打中,质量分布决定倒下后怎么翻滚,物理动画混合决定受击过渡是否自然,Ragdoll 决定死亡或击飞是否可信,碰撞通道决定谁该与谁互动,性能优化则决定这些效果能不能在真实关卡里跑起来。UE5.8 的工具链把这些环节串得更顺,但最终效果仍然取决于每个旋钮背后的人是否理解它在模拟什么。

下次当你看到角色被一记重击掀翻在地,不妨暂停一下,打开 Physics Asset 编辑器,看看那颗红色质心标记到底在哪里。很多时候,一个更真实的倒下,只需要把胶囊长度缩短 10 厘米,或者把躯干密度调大 50。