SuperAPI AI 工具集

physics-and-chaos

编程与开发

查看项目

更新于 11-06 16:19

技能介绍

本技能聚焦虚幻引擎(UE)中的 Chaos 物理引擎,面向 C++ 开发,讲解碰撞、物理模拟与世界查询三大类常见需求。Chaos 是 UE 的物理引擎,多数玩法需要它提供三样东西:碰撞(什么阻挡/重叠什么)、查询(用射线/扫描询问世界)以及偶尔的模拟(刚体、布娃娃、约束)。碰撞设置错误是“我的重叠/命中从不触发”这类 bug 最常见的来源。

适用场景包括:设置什么与什么碰撞(通道、预设、逐通道响应);制作触发体积或检测 Actor 之间的重叠;对世界进行线/形状扫描(瞄准、地面检测、交互检测);模拟物理对象——启用刚体物理、施加力/冲量;构建布娃娃或用 UPhysicsConstraintComponent 约束物体;调试“重叠从不触发”“扫描未命中”或“物理未模拟”等问题。

碰撞模型——每个组件有三个控制项。每个 UPrimitiveComponent 都有三个碰撞控制项:对象类型(ECollisionChannel),即该组件是什么,内置有 ECC_WorldStatic、ECC_WorldDynamic、ECC_Pawn、ECC_PhysicsBody、ECC_Visibility、ECC_Camera,自定义通道在运行时映射到 ECC_GameTraceChannel1–ECC_GameTraceChannel50(5.8 中从 18 扩展到 50);逐通道响应(ECollisionResponse),即对每个通道如何反应,包括 ECR_Ignore、ECR_Overlap、ECR_Block;碰撞启用模式(ECollisionEnabled::Type),即该形状参与什么,包括 NoCollision(无物理、无查询)、QueryOnly(重叠/扫描,无刚体模拟,最适合触发体积)、PhysicsOnly(仅刚体模拟,扫描不会命中它)、QueryAndPhysics(两者兼具,多数模拟对象的默认值)。Block 需要双方都为对方对象类型设置 ECR_Block。对于重叠事件,双方都需要 ECR_Overlap 响应且 bGenerateOverlapEvents = true。

碰撞预设将对象类型与响应打包为命名配置,可用 SetCollisionProfileName(TEXT("Trigger")) 应用项目预设或 Project Settings → Collision 中定义的预设。应用预设会覆盖逐通道覆盖,因此细粒度的 SetCollisionResponseToChannel 调用应在预设之后进行。

命中与重叠事件需在 BeginPlay 中绑定(而非构造函数,那里没有世界)。处理函数必须是 UFUNCTION(),因为动态委托需要 UObject 反射。对于模拟物体上的命中事件,还需在物体上启用 Simulation Generates Hit Events(FBodyInstance::bNotifyRigidBodyCollision)。

扫描与查询部分介绍了线扫描(LineTraceSingleByChannel)、球体扫描(SweepSingleByChannel)和重叠查询(OverlapMultiByChannel),以及 FHitResult 的常用字段:Time(沿扫描的 0–1)、Distance、Location(接触时的形状中心)、ImpactPoint(表面接触点)、ImpactNormal、GetActor()、GetComponent()、BoneName、PhysMaterial。多结果变体(LineTraceMultiByChannel、SweepMultiByChannel)返回直到并包括第一个阻挡的所有重叠,适用于子弹穿过植被等场景。

刚体模拟部分说明如何启用物理模拟(需要网格体资源上有简单碰撞)、设置质量、施加力与冲量。AddForce 在每个物理子步累积;AddImpulse 在当前步应用一次。阻尼位于 FBodyInstance 上(可通过 GetBodyInstance() 访问):LinearDamping 和 AngularDamping。模拟物体必须具有简单碰撞(球体/盒体/胶囊/凸包),复杂的逐三角形碰撞无法驱动刚体模拟。

布娃娃通过 UPhysicsAsset(在 Physics Asset Editor 中制作)运行,它为 USkeletalMeshComponent 定义逐骨骼物体和约束。物理约束 UPhysicsConstraintComponent 封装 FConstraintInstance,连接两个模拟物体,可设置线性/角度限制、绑定约束断裂事件,并在运行时用 BreakConstraint() 断开关节。FConstraintInstance 还支持驱动(马达):SetLinearPositionDrive、SetAngularDriveMode。

物理材质 UPhysicalMaterial 存储表面属性,被 UStaticMesh 和 UPrimitiveComponent 引用,关键字段有 Friction、StaticFriction、Restitution、Density、SurfaceType(EPhysicalSurface)。可从命中读取 SurfaceType 来驱动效果(脚步声、粒子发射器)。

碰撞复杂度分为简单(图元/凸包,可模拟,查询开销低,刚体模拟必需)和复杂(逐三角形,不可模拟,用于精确静态查询如地形、精细网格)。可在网格体资源的碰撞设置中设置,也可在组件上覆盖。使用 FCollisionQueryParams::bTraceComplex = true 查询复杂碰撞。

常见陷阱包括:重叠从不触发(双方都需要对彼此对象类型的 ECR_Overlap 响应且双方 bGenerateOverlapEvents = true;一方为 ECR_Block 而另一方为 ECR_Overlap 仍会产生重叠,但只有一方触发);命中事件从不触发(需启用 Simulation Generates Hit Events,且物理模拟必须启用);扫描什么都未命中(检查目标的 ECollisionEnabled,NoCollision 或 PhysicsOnly 会让它们对扫描不可见);在复杂碰撞网格上模拟(物理模拟需要简单碰撞);忘记 AddIgnoredActor(this)(扫描命中自身 Actor 的碰撞形状);处理函数不是 UFUNCTION()(AddDynamic 静默失败);先应用预设再逐通道覆盖(SetCollisionProfileName 会重置所有响应,应在调用后设置逐通道响应);力与冲量单位(AddForce 为牛顿,每个子步应用;AddImpulse 为 kg·cm/s,应用一次);SetSimulatePhysics(true) 静默无效(网格没有简单碰撞,或 SetCollisionEnabled 为 NoCollision/QueryOnly)。

版本说明:Chaos 在 UE5 中取代 PhysX 成为默认物理引擎。Chaos 求解器运行确定性固定子步,由 UPhysicsSettings::AsyncFixed 控制(Project Settings → Physics → Simulation → Use Async Scene)。FBodyInstance 在 UE5 中保持稳定;求解器内部与 PhysX 不同,但 UPrimitiveComponent API 未变。