UE 物理与布料系统完全指南
前言
UE 的 Physics Asset(物理资产)和 Cloth(布料)系统让角色在非动画状态时依然能「活着」——头发会随移动摆动,披风会被风吹起,碰撞后肢体自然倒下(Ragdoll)。这些效果不依赖美术关键帧,全部由物理引擎实时计算,是现代 AAA 游戏角色动画不可或缺的组成部分。
一、Physics Asset 概述
1.1 什么是 Physics Asset
Physics Asset 是一组由 Physics Body(物理体)组成的集合,每个 Body 对应角色的一个骨骼,通过 Constraint(约束) 连接。比如:
Root (Physics Body: 无碰撞)
↓ Constraint
pelvis (Body: Dynamic)
↓ Constraint
spine_01 (Body: Kinematic) → 锁住,不参与物理
↓ Constraint
clavicle_l (Body: Kinematic)
↓ Constraint
upperarm_l (Body: Dynamic) → 布料化时变为 Dynamic
1.2 Physics Body 类型
| 类型 | 行为 | 用途 |
|---|---|---|
| Kinematic | 美术驱动(跟随骨骼动画) | 默认,大部位 |
| Dynamic | 物理引擎驱动 | 头发、披风、胸部 |
| Fixed | 完全不动 | 锁死关节 |
1.3 创建 Physics Asset
Content Browser → 骨骼网格体右键 → Create → Physics Asset → Accept
UE 会自动生成 Physics Body,也可以手动调整分布和类型。
二、Ragdoll 物理
2.1 什么是 Ragdoll
Ragdoll 是角色「死亡」或「严重受击」时,物理引擎接管肢体控制的状态。骨骼从 Kinematic(动画驱动)切换为 Dynamic(物理驱动),肢体在重力、碰撞作用下自然倒下。
2.2 Ragdoll 切换代码
void AMyCharacter::EnableRagdoll() {
USkeletalMeshComponent* Mesh = GetMesh();
// 第一步:让所有 Body 变为 Dynamic
Mesh->SetAllBodiesSimulatePhysics(true);
Mesh->SetSimulatePhysics(true);
Mesh->WakeAllRigidBodies();
// 第二步:关闭 Character Movement 的碰撞
GetCharacterMovement()->DisableMovement();
GetCharacterMovement()->StopMovementImmediately();
// 第三步:将速度传递给物理体(模拟冲击力)
FVector Impulse = GetVelocity() * 0.5f;
Mesh->AddImpulse(Impulse, FName("pelvis"));
}
void AMyCharacter::DisableRagdoll() {
USkeletalMeshComponent* Mesh = GetMesh();
// 停止物理模拟
Mesh->SetAllBodiesSimulatePhysics(false);
Mesh->SetSimulatePhysics(false);
Mesh->bPhysics 애 = false;
// 恢复运动
GetCharacterMovement()->SetMovementMode(MOVE_Walking);
// 强制对齐到当前动画姿势(消除物理遗留偏移)
Mesh->ForceTPose();
}
2.3 Get Up Animation
角色从 Ragdoll 恢复站立时,需要播放「起身动画」:
检测:从 Ragdoll 状态到速度 < 阈值(表示落地静止)
→ 播放 GetUp_FromProne 或 GetUp_FromSupine
→ 完成后恢复到 Locomotion 状态机
三、Constraint 约束系统
3.1 什么是 Constraint
Constraint 是连接两个 Physics Body 的关节,控制它们之间的运动自由度:
| 约束类型 | 约束内容 |
|---|---|
| Ball Socket | 三个旋转自由度(肩关节) |
| Hinge | 一个旋转自由度(肘关节) |
| Prismatic | 一个平移自由度(滑轨) |
| Physic Constraint | 六个自由度全部可控 |
3.2 约束属性
// C++ 创建并配置约束
UPhysicsConstraintComponent* Constraint =
NewObject<UPhysicsConstraintComponent>(this);
Constraint->AttachToComponent(Mesh,
FAttachmentTransformRules::KeepRelativeTransform);
Constraint->SetConstrainedComponents(
Mesh, FName("pelvis"), // Body A
Mesh, FName("spine_01") // Body B
);
// 设置角度限制(防止关节过度弯曲)
Constraint->SetAngularSwing1Limit(
EAngularConstraintMotion::ACM_Limited, 45.0f);
Constraint->SetAngularSwing2Limit(
EAngularConstraintMotion::ACM_Limited, 45.0f);
Constraint->SetAngularTwistLimit(
EAngularConstraintMotion::ACM_Limited, 30.0f);
3.3 常见问题
肢体穿模:调整 Physics Body 碰撞配置,设置 Collision Response = Block All
关节松散:增大 Angular Swing1 Motion / 2 Motion 的线性阻尼
肢体折叠:启用 Projection 功能,自动纠正过大的分离
四、Cloth 布料系统
4.1 UE 的两套布料系统
| 系统 | 引擎 | 特点 |
|---|---|---|
| PhysX Clothing | 老版(4.4) | 经典,稳定性好 |
| Chaos Clothing | UE 5 新版 | 性能更好,功能更丰富 |
UE 5 推荐使用 Chaos Clothing。
4.2 创建布料资产
骨骼网格体 → 双击打开 → 选择骨骼 → 右键 → Create Clothing
→ 打开 Clothing 面板
→ 选择想要布料化的顶点组(LOD0)
→ 设置 Max Distance(最大形变距离)
→ Apply
4.3 关键参数
| 参数 | 含义 | 建议值 |
|---|---|---|
Max Distance |
布料与骨骼最大偏离距离 | 2~10cm |
Self Collision Thickness |
自碰撞厚度 | 1cm |
Damping |
阻尼(越大越不易震荡) | 0.1~0.5 |
Stiffness |
刚度(越大越不易变形) | 0.5~1.0 |
Gravity Scale |
重力缩放 | 0.5~1.0 |
4.4 运行时启用/禁用布料
// 蓝图等效
USkeletalMeshComponent* Mesh = GetMesh();
// 启用布料
Mesh->EnableClothSetup();
Mesh->SetSkeletalMeshComponentClothTick(Mesh, true);
// 禁用布料(性能优化)
Mesh->SetSkeletalMeshComponentClothTick(Mesh, false);
4.5 布料与碰撞
布料需要与角色身体碰撞才能真实:
// 启用布料与骨骼网格体碰撞
Mesh->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
Mesh->SetGenerateOverlapEvents(true);
// 身体 Physics Body 需要设置为 GenerateOverlapEvents = true
// 否则布料会穿进身体
五、Physical Animation Component
5.1 什么是 Physical Animation
Physical Animation 是让部分骨骼由物理驱动、部分骨骼由动画驱动的技术。典型场景:角色上楼梯时,腿部用动画(精确控制),头发和披风用物理(自然摆动)。
5.2 配置 Physical Animation
UPhysicalAnimationComponent* PhysAnim =
NewObject<UPhysicalAnimationComponent>(this);
PhysAnim->RegisterComponent();
PhysAnim->AttachToComponent(Mesh,
FAttachmentTransformRules::KeepRelativeTransform);
// 设置哪些骨骼由物理驱动
FPhysicalAnimationData PhysData;
PhysData.bIsLocalSimulation = false;
PhysData.OrientationPriority = 0;
PhysData.AngularVelocityPriority = 1;
PhysAnim->SetSkeletalMeshComponent(Mesh);
PhysAnim->ApplyPhysicalAnimationSettingsBelow(FName("pelvis"), PhysData);
// pelvis 以下的骨骼全部交给物理处理
5.3 典型应用
场景:开放世界 RPG,骑马时披风飘动
方案:
- 披风相关骨骼(spine_02, clavicle_l/r)→ Physical Animation
- 其他骨骼 → 正常动画驱动
- Physics Asset 中披风相关 Body 设置为 Dynamic
六、性能优化
6.1 Physics LOD
Physics Asset 支持 LOD,远处时减少物理体数量:
// 设置 Physics LOD 级别
Mesh->SetPhysicsLOD(int32(LODIndex));
// LOD 级别在 Physics Asset 中配置
// Project Settings → Physics → Physical Animation LOD Count
6.2 布料 Tick 分级
// 根据重要性设置布料 Tick 频率
Mesh->SetClothLODBias(1); // 跳过最高 LOD 的细节
Mesh->SetClothMaxDistanceScale(0.5f); // 缩小最大形变范围
6.3 布料调试
开启布料可视化:
Show → Visualize → Cloth
查看布料顶点:
Select Cloth Element in Skeletal Mesh Editor
七、总结
Physics Asset + Cloth + Physical Animation 构成了 UE 角色的「物理层」:
– Ragdoll 让角色死亡和受击真实可信
– Constraint 精确控制关节运动范围,防止肢体折叠
– Cloth 让头发、披风等自然随动
– Physical Animation 实现了动画与物理的混合驱动
– LOD + Tick 分级 确保在开放世界中依然保持性能
这三个子系统配合分层动画,就构成了完整的 AAA 级角色动画体系。
本文收录于 Matrix4x4 AI 编程与游戏开发资源库