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 在资源栈里的位置。

architecture-beta
    group skeletal(skeleton:SkeletalMesh)
    group phat(cloud:PhysicsAsset)
    group anims(database:AnimationBlueprint)
    group world(server:World)

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

    mesh:skeleton --> body:phat
    mesh:skeleton --> constraint:phat
    body:phat --> constraint:phat
    abp:animations --> skc:component
    mesh:render --> skc:component
    phat:physics --> skc:component
    skc:component --> world:simulate

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

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 刚体。

质量分布与质心

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)

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

物理动画混合

直接切到 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,比如钝器重击用慢速上升的曲线,箭矢用瞬时峰值然后快速回落。

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 降低关节旋转速度,避免四肢甩成不自然角度。

碰撞通道配置

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 可视化,调试效率比旧版本高很多。

性能优化

物理模拟是 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 相关改进

相比 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。