UE 物理与布料系统完全指南

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 编程与游戏开发资源库

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部