跳转至

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);
    }
}

物理材质

创建物理材质

  1. Content Browser > 右键单击 > 物理 > 物理材质
  2. 配置属性:
  3. 摩擦力:0.0 - 1.0
  4. 恢复系数(弹性):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

// Plugin: Enable "Chaos" plugin
// Create Geometry Collection asset for destructible objects

销毁几何集合

// 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,无论其类型如何。

要添加物理主体组件:

  1. 在内容浏览器中选择 Actor。
  2. 在细节面板中,单击添加组件按钮。
  3. 从组件列表中,选择物理主体。
  4. 配置所需属性。

物理主体属性

物理主体组件具有许多属性,可用于控制其行为。其中一些最常用的属性包括:

  • 质量:主体的质量。它影响主体对力的反应方式。
  • 重力:此属性控制重力是否影响主体。
  • 线性阻尼:此属性控制主体随时间衰减线性速度的速率。
  • 角阻尼:此属性控制主体随时间衰减角速度的速率。
  • 碰撞启用:此属性控制主体是否会与其他物理主体碰撞。

物理主体类型

有几种类型的物理主体:

  • 静态:静态主体不参与模拟。它们用于表示环境中不移动的物体。
  • 动态:动态主体参与模拟。它们受力和扭矩的影响,可以与其他物理主体碰撞。
  • 运动学:运动学主体参与模拟,但通过代码或动画直接驱动。它们不会对力或扭矩作出反应。

碰撞

碰撞是物理主体之间的交互。它们可以用于防止物体相互穿过,或用于触发游戏玩法事件。

在 Unreal Engine 中,有几种类型的碰撞:

  • 阻挡:主体会阻挡彼此的移动。
  • 重叠:主体可以相互穿过,但会生成重叠事件。
  • 忽略:主体会完全忽略彼此。

配置碰撞

物理主体之间的碰撞行为由 Actor 或组件上的碰撞设置属性控制。要配置碰撞:

  1. 在细节面板中选择 Actor 或组件。
  2. 在碰撞部分下,配置所需属性。
  3. 通过设置碰撞启用属性为查询和物理来启用碰撞。

碰撞事件

碰撞事件可用于触发游戏玩法事件。有两种类型的碰撞事件:

  • 碰撞事件:当两个物理主体之间的碰撞开始时生成的。
  • 重叠事件:当两个物理主体开始或停止重叠时生成的。

要接收碰撞事件,需要将事件处理程序绑定到物理主体组件上的相应事件。

物理约束

物理约束限制了物理主体之间的相对运动。它们可用于创建关节、铰链和其他类型的连接。

Unreal Engine 中有几种类型的物理约束:

  • 固定:约束将两个物理主体锁定在一起。
  • 铰链:约束允许两个物理主体围绕一个轴相对旋转。
  • 球形:约束允许两个物理主体在所有方向上相对旋转。
  • 棱柱:约束允许两个物理主体沿一个轴相对平移。

创建物理约束

要创建物理约束,需要向 Actor 添加一个物理约束组件。该组件将处理 Actor 之间的物理约束。

要添加物理约束组件:

  1. 在内容浏览器中选择 Actor。
  2. 在细节面板中,单击添加组件按钮。
  3. 从组件列表中,选择物理约束。
  4. 配置所需属性。

物理约束属性

物理约束组件具有许多属性,可用于控制其行为。其中一些最常用的属性包括:

  • 约束类型:约束的类型。
  • 线性限制:约束允许的线性运动量。
  • 角限制:约束允许的角运动量。
  • 硬度:约束抵抗运动的刚度。
  • 阻尼:约束随时间衰减运动的速率。

物理控制

物理控制用于将力或扭矩施加到物理主体上。它们可用于推动物体、旋转物体或创建复杂的物理行为。

Unreal Engine 中有几种类型的物理控制:

  • 力:力是物理主体上的线性推力。
  • 扭矩:扭矩是物理主体上的旋转力。
  • 脉冲:脉冲是施加到物理主体上的瞬时力或扭矩。

应用物理控制

要应用物理控制,需要获取对要控制的物理主体组件的引用,然后调用相应的方法。

例如,要对物理主体施加力:

// 获取对物理主体组件的引用
UPhysicsBodyComponent* PhysicsBody = GetComponentByClass<UPhysicsBodyComponent>();

// 对物理主体施加力
PhysicsBody->AddForce(FVector(0.0f, 0.0f, 1000.0f));

物理控制类型

有几种类型的物理控制:

  • 力:力是物理主体上的线性推力。
  • 扭矩:扭矩是物理主体上的旋转力。
  • 脉冲:脉冲是施加到物理主体上的瞬时力或扭矩。

物理控制可用于创建各种不同的行为,例如:

  • 推动物体
  • 旋转物体
  • 创建爆炸
  • 创建角色运动

性能提示

以下部分提供了一些用于优化物理性能的提示:

  • 使用简单的碰撞形状:简单的碰撞形状(例如盒子、球体、胶囊体)比复杂的碰撞形状(例如凸包、三角网格)计算成本更低。
  • 减少物理主体的数量:场景中物理主体越多,物理模拟的计算成本就越高。
  • 使用碰撞预设:碰撞预设是一种快速配置碰撞行为的便捷方式,无需手动设置每个属性。
  • 使用物理 LOD:物理 LOD(细节层次)可用于降低远处物体的物理模拟质量。

提示

在移动平台上开发时,请使用简单碰撞形状并减少物理主体的数量,以确保可接受的性能。

本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 cl/Claude-Code-Game-Studios