Unreal Engine 5.7 — 物理 Module Reference¶
最后验证: 2026-02-13 Knowledge Gap: UE 5.7 Chaos Physics 改进
概述¶
UE 5 使用 Chaos Physics(取代了 UE 4 中的 PhysX):
- 更好的性能
- 破坏支持
- 车辆物理改进
刚体物理¶
在静态网格体上启用物理¶
UStaticMeshComponent* MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("Mesh"));
MeshComp->SetSimulatePhysics(true);
MeshComp->SetEnableGravity(true);
MeshComp->SetMassOverrideInKg(NAME_None, 50.0f); // 50 kg
施加力¶
// Apply impulse (instant velocity change)
MeshComp->AddImpulse(FVector(0, 0, 1000), NAME_None, true);
// Apply force (continuous)
MeshComp->AddForce(FVector(0, 0, 500));
// Apply torque (rotation)
MeshComp->AddTorqueInRadians(FVector(0, 0, 100));
碰撞¶
碰撞通道¶
// Project Settings > Engine > Collision
// Define custom collision channels and responses
// Set collision in C++
MeshComp->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
MeshComp->SetCollisionObjectType(ECollisionChannel::ECC_Pawn);
MeshComp->SetCollisionResponseToAllChannels(ECR_Block);
MeshComp->SetCollisionResponseToChannel(ECC_Camera, ECR_Ignore);
碰撞事件¶
// Enable collision events
MeshComp->SetNotifyRigidBodyCollision(true);
// Bind to OnComponentHit
MeshComp->OnComponentHit.AddDynamic(this, &AMyActor::OnHit);
UFUNCTION()
void AMyActor::OnHit(UPrimitiveComponent* HitComp, AActor* OtherActor,
UPrimitiveComponent* OtherComp, FVector NormalImpulse, const FHitResult& Hit) {
UE_LOG(LogTemp, Warning, TEXT("Hit %s"), *OtherActor->GetName());
}
重叠事件¶
// Enable overlap events
MeshComp->SetGenerateOverlapEvents(true);
// Bind to OnComponentBeginOverlap
MeshComp->OnComponentBeginOverlap.AddDynamic(this, &AMyActor::OnOverlapBegin);
UFUNCTION()
void AMyActor::OnOverlapBegin(UPrimitiveComponent* OverlappedComp, AActor* OtherActor,
UPrimitiveComponent* OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult& SweepResult) {
UE_LOG(LogTemp, Warning, TEXT("Overlapped %s"), *OtherActor->GetName());
}
射线检测(Line Traces)¶
单次射线检测¶
FHitResult HitResult;
FVector Start = GetActorLocation();
FVector End = Start + GetActorForwardVector() * 1000.0f;
FCollisionQueryParams QueryParams;
QueryParams.AddIgnoredActor(this);
// Perform trace
bool bHit = GetWorld()->LineTraceSingleByChannel(
HitResult,
Start,
End,
ECC_Visibility,
QueryParams
);
if (bHit) {
UE_LOG(LogTemp, Warning, TEXT("Hit: %s"), *HitResult.GetActor()->GetName());
DrawDebugLine(GetWorld(), Start, HitResult.Location, FColor::Red, false, 2.0f);
}
多次射线检测¶
TArray<FHitResult> HitResults;
bool bHit = GetWorld()->LineTraceMultiByChannel(
HitResults,
Start,
End,
ECC_Visibility,
QueryParams
);
for (const FHitResult& Hit : HitResults) {
UE_LOG(LogTemp, Warning, TEXT("Hit: %s"), *Hit.GetActor()->GetName());
}
扫描(Thick Trace)¶
FHitResult HitResult;
FCollisionShape Sphere = FCollisionShape::MakeSphere(50.0f);
bool bHit = GetWorld()->SweepSingleByChannel(
HitResult,
Start,
End,
FQuat::Identity,
ECC_Visibility,
Sphere,
QueryParams
);
角色移动¶
角色移动组件¶
// Built into ACharacter class
UCharacterMovementComponent* MoveComp = GetCharacterMovement();
// Configure movement
MoveComp->MaxWalkSpeed = 600.0f;
MoveComp->JumpZVelocity = 600.0f;
MoveComp->AirControl = 0.2f;
MoveComp->GravityScale = 1.0f;
MoveComp->bOrientRotationToMovement = true;
添加移动输入¶
// In Character class
void AMyCharacter::MoveForward(float Value) {
if (Value != 0.0f) {
AddMovementInput(GetActorForwardVector(), Value);
}
}
void AMyCharacter::MoveRight(float Value) {
if (Value != 0.0f) {
AddMovementInput(GetActorRightVector(), Value);
}
}
物理材质¶
创建物理材质¶
- Content Browser > 右键单击 > 物理 > 物理材质
- 配置属性:
- 摩擦力:0.0 - 1.0
- 恢复系数(弹性):0.0 - 1.0
指定物理材质¶
// In static mesh editor: Physics > Phys Material Override
// Or in C++:
MeshComp->SetPhysMaterialOverride(PhysicalMaterial);
约束(物理关节)¶
物理约束组件¶
UPhysicsConstraintComponent* Constraint = CreateDefaultSubobject<UPhysicsConstraintComponent>(TEXT("Constraint"));
Constraint->SetConstrainedComponents(ComponentA, NAME_None, ComponentB, NAME_None);
// Configure constraint
Constraint->SetLinearXLimit(ELinearConstraintMotion::LCM_Limited, 100.0f);
Constraint->SetLinearYLimit(ELinearConstraintMotion::LCM_Locked, 0.0f);
Constraint->SetLinearZLimit(ELinearConstraintMotion::LCM_Free, 0.0f);
Constraint->SetAngularSwing1Limit(EAngularConstraintMotion::ACM_Limited, 45.0f);
破坏(Chaos Destruction)¶
启用 Chaos Destruction¶
销毁几何集合¶
// Fracture mesh in Chaos editor
// In game, apply damage:
GeoComp->ApplyPhysicsField(/* Field parameters */);
Performance Tips¶
物理优化¶
// Simplify collision shapes (use simple primitives)
MeshComp->SetCollisionEnabled(ECollisionEnabled::NoCollision); // Disable when not needed
// Use Physics Asset for skeletal meshes (simplified collision)
// Don't simulate physics for distant objects
// Reduce physics substeps:
// Project Settings > Engine > Physics > Max Substep Delta Time
调试¶
物理调试可视化¶
// Console commands:
// show collision - Show collision shapes
// p.Chaos.DebugDraw.Enabled 1 - Show Chaos debug
// pxvis collision - Visualize collision
// Draw debug shapes:
DrawDebugSphere(GetWorld(), Location, Radius, 12, FColor::Green, false, 2.0f);
DrawDebugBox(GetWorld(), Location, Extent, FColor::Red, false, 2.0f);
来源¶
- https://docs.unrealengine.com/5.7/en-US/physics-in-unreal-engine/
- https://docs.unrealengine.com/5.7/en-US/chaos-physics-overview-in-unreal-engine/
注意
仅翻译源代码片段中的注释。不要翻译字符串文字或用户可见的文本。
源代码片段中未注释掉的代码行必须保持完全不变。仅翻译位于代码上方的注释行。
警告
不要翻译命令、文件路径、URL 或代码标识符。仅翻译叙述性文本。
本指南中使用的示例仅用于说明目的。UI 元素名称和键盘快捷键可能会根据你所使用的 Unreal Engine 版本而有所不同。
物理系统概述¶
抽象
Unreal Engine 中的物理系统 是一个框架,用于模拟刚体动力学、碰撞检测以及场景中 Actor 之间的交互。它基于 Chaos 物理系统构建,该系统提供了用于创建逼真物理模拟的确定性求解器和多种功能。
在本模块中,你将学习到:
提示
本模块假定你已了解 Unreal Engine 编辑器的基础知识。如果你还不熟悉编辑器,请先查看 Unreal Engine 文档 中的入门指南。
Chaos 物理系统概述¶
Chaos 是 Unreal Engine 5 的默认物理系统。它取代了旧版 PhysX 物理引擎,并提供了一套统一的功能集,用于模拟:
- 刚体动力学 — 模拟受力和扭矩影响的刚性物体的运动。
- 软体动力学 — 模拟可变形物体,如布料、头发和可破坏物。
- 流体模拟 — 使用粒子系统模拟液体和气体。
- 车辆物理 — 模拟车辆及其与环境的交互。
- 角色物理 — 模拟角色与其环境之间的物理交互。
Chaos 设计为确定性的,这意味着在相同输入下,它每次都会产生相同的结果。这对于依赖可重现物理模拟的游戏玩法机制尤为重要。
Chaos 的主要特性¶
- 高性能:Chaos 经过优化,可在多个 CPU 核心上并行运行,并且可以扩展到大型场景。
- 灵活性:Chaos 提供了一套全面的 API,用于创建自定义物理行为。
- 稳定性:Chaos 设计为数值稳定,即使在复杂的模拟场景中也是如此。
关键概念¶
以下部分介绍了与 Chaos 相关的一些关键概念:
- 物理主体:物理主体是参与物理模拟的 Actor 或组件。它们具有质量、位置、旋转和速度等属性。
- 碰撞:碰撞是物理主体之间的交互。它们可以用于防止物体相互穿过,或用于触发游戏玩法事件。
- 约束:约束限制了物理主体之间的相对运动。它们可用于创建关节、铰链和其他类型的连接。
- 物理控制:物理控制用于将力或扭矩施加到物理主体上。它们可用于推动物体、旋转物体或创建复杂的物理行为。
物理主体¶
物理主体是参与物理模拟的 Actor 或组件。它们具有质量、位置、旋转和速度等属性。物理主体可以有两种类型:
- 静态:静态主体不参与模拟。它们用于表示环境中不移动的物体。
- 动态:动态主体参与模拟。它们受力和扭矩的影响,可以与其他物理主体碰撞。
创建物理主体¶
要创建物理主体,需要向 Actor 添加一个物理主体组件。该组件将处理 Actor 的物理模拟。你可以将物理主体组件添加到任何 Actor,无论其类型如何。
要添加物理主体组件:
- 在内容浏览器中选择 Actor。
- 在细节面板中,单击添加组件按钮。
- 从组件列表中,选择物理主体。
- 配置所需属性。
物理主体属性¶
物理主体组件具有许多属性,可用于控制其行为。其中一些最常用的属性包括:
- 质量:主体的质量。它影响主体对力的反应方式。
- 重力:此属性控制重力是否影响主体。
- 线性阻尼:此属性控制主体随时间衰减线性速度的速率。
- 角阻尼:此属性控制主体随时间衰减角速度的速率。
- 碰撞启用:此属性控制主体是否会与其他物理主体碰撞。
物理主体类型¶
有几种类型的物理主体:
- 静态:静态主体不参与模拟。它们用于表示环境中不移动的物体。
- 动态:动态主体参与模拟。它们受力和扭矩的影响,可以与其他物理主体碰撞。
- 运动学:运动学主体参与模拟,但通过代码或动画直接驱动。它们不会对力或扭矩作出反应。
碰撞¶
碰撞是物理主体之间的交互。它们可以用于防止物体相互穿过,或用于触发游戏玩法事件。
在 Unreal Engine 中,有几种类型的碰撞:
- 阻挡:主体会阻挡彼此的移动。
- 重叠:主体可以相互穿过,但会生成重叠事件。
- 忽略:主体会完全忽略彼此。
配置碰撞¶
物理主体之间的碰撞行为由 Actor 或组件上的碰撞设置属性控制。要配置碰撞:
- 在细节面板中选择 Actor 或组件。
- 在碰撞部分下,配置所需属性。
- 通过设置碰撞启用属性为查询和物理来启用碰撞。
碰撞事件¶
碰撞事件可用于触发游戏玩法事件。有两种类型的碰撞事件:
- 碰撞事件:当两个物理主体之间的碰撞开始时生成的。
- 重叠事件:当两个物理主体开始或停止重叠时生成的。
要接收碰撞事件,需要将事件处理程序绑定到物理主体组件上的相应事件。
物理约束¶
物理约束限制了物理主体之间的相对运动。它们可用于创建关节、铰链和其他类型的连接。
Unreal Engine 中有几种类型的物理约束:
- 固定:约束将两个物理主体锁定在一起。
- 铰链:约束允许两个物理主体围绕一个轴相对旋转。
- 球形:约束允许两个物理主体在所有方向上相对旋转。
- 棱柱:约束允许两个物理主体沿一个轴相对平移。
创建物理约束¶
要创建物理约束,需要向 Actor 添加一个物理约束组件。该组件将处理 Actor 之间的物理约束。
要添加物理约束组件:
- 在内容浏览器中选择 Actor。
- 在细节面板中,单击添加组件按钮。
- 从组件列表中,选择物理约束。
- 配置所需属性。
物理约束属性¶
物理约束组件具有许多属性,可用于控制其行为。其中一些最常用的属性包括:
- 约束类型:约束的类型。
- 线性限制:约束允许的线性运动量。
- 角限制:约束允许的角运动量。
- 硬度:约束抵抗运动的刚度。
- 阻尼:约束随时间衰减运动的速率。
物理控制¶
物理控制用于将力或扭矩施加到物理主体上。它们可用于推动物体、旋转物体或创建复杂的物理行为。
Unreal Engine 中有几种类型的物理控制:
- 力:力是物理主体上的线性推力。
- 扭矩:扭矩是物理主体上的旋转力。
- 脉冲:脉冲是施加到物理主体上的瞬时力或扭矩。
应用物理控制¶
要应用物理控制,需要获取对要控制的物理主体组件的引用,然后调用相应的方法。
例如,要对物理主体施加力:
// 获取对物理主体组件的引用
UPhysicsBodyComponent* PhysicsBody = GetComponentByClass<UPhysicsBodyComponent>();
// 对物理主体施加力
PhysicsBody->AddForce(FVector(0.0f, 0.0f, 1000.0f));
物理控制类型¶
有几种类型的物理控制:
- 力:力是物理主体上的线性推力。
- 扭矩:扭矩是物理主体上的旋转力。
- 脉冲:脉冲是施加到物理主体上的瞬时力或扭矩。
物理控制可用于创建各种不同的行为,例如:
- 推动物体
- 旋转物体
- 创建爆炸
- 创建角色运动
性能提示¶
以下部分提供了一些用于优化物理性能的提示:
- 使用简单的碰撞形状:简单的碰撞形状(例如盒子、球体、胶囊体)比复杂的碰撞形状(例如凸包、三角网格)计算成本更低。
- 减少物理主体的数量:场景中物理主体越多,物理模拟的计算成本就越高。
- 使用碰撞预设:碰撞预设是一种快速配置碰撞行为的便捷方式,无需手动设置每个属性。
- 使用物理 LOD:物理 LOD(细节层次)可用于降低远处物体的物理模拟质量。
提示
在移动平台上开发时,请使用简单碰撞形状并减少物理主体的数量,以确保可接受的性能。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/Claude-Code-Game-Studios