UE5.8 Geometry Collection 与 Chaos 破坏系统

📑 目录

UE5.8 Geometry Collection 与 Chaos 破坏系统

一、一面墙怎么塌才算真实

设想一个场景:玩家在一座废弃工厂的二楼走廊,用火箭筒对准承重墙扣下扳机。火光闪过之后,墙面上先崩出几块大板,裂缝顺着砖缝蔓延,整面墙像被撕开一样朝走廊内侧倾倒,碎块砸穿地板,扬起烟尘。策划希望这一幕在 UE5 里全程实时演算,而不是播一段预渲染动画。

这个需求落到技术层面,核心就是 Chaos 物理引擎的破坏系统。Chaos 从 UE4.23 开始替代 PhysX 成为默认物理后端,到 UE5 已经能支撑大规模的刚体破坏。Geometry Collection 则是 Chaos 处理可破坏物体的专用资产类型,它把静态网格拆成一组带连接关系的碎片,并在运行时根据受力、Field、事件等条件逐步断开连接。

这篇文章围绕一面墙、一根石柱、一个可破坏场景,把 Geometry Collection 从资产创建、破碎设置、Field 控制、Gameplay 联动到网络同步的各个环节串起来。

二、Geometry Collection 资产创建

2.1 从 Static Mesh 到 Geometry Collection

Geometry Collection 并不是直接拖进关卡的模型。它的来源通常是 Static Mesh,通过 Fracture Editor 或者右键菜单 Convert to Geometry Collection 生成。生成之后,原网格被切分成若干 Convex(凸包)碎片,每个碎片在 Chaos 里都是一个独立的 Rigid Body。

转化过程会保留原始网格的材质 ID、UV、碰撞凸包。编辑器把结果存成 .uasset,内部结构大概如下:

flowchart TD
    raw_mesh --> vertices
    vertices --> convexes
    convexes --> bonds
    bonds --> transform

每个碎片都有质量、惯性张量、摩擦系数和恢复系数。连接关系 Bonds 决定哪些碎片在初始状态下粘在一起。没有 Bond 的碎片从第一帧就开始自由运动。

2.2 关键参数

在 Geometry Collection 的细节面板里,有几组参数直接影响模拟表现:

  • Initial Velocity Type:静止、随机、从 Field 读取。墙壁爆破通常选 None,让爆炸 Field 去驱动。
  • Object Type:Dynamic 会受重力影响并参与碰撞;Kinematic 只按外部输入运动;Sleeping 在受力前保持静止。
  • Collision Type:Full 使用凸包精确碰撞,Shard 是简化凸包,None 只做视觉破碎。
  • Mass:默认按体积和密度自动计算。石柱如果材质密度填错,塌下来会像泡沫。
  • Anchored:勾选后碎片被固定在世界空间,适合地基、楼板边缘。

这些参数没有放之四海皆准的数值。混凝土墙和木质货箱的密度、破碎尺寸完全不同,需要分别调试。

三、Fracture 工具与破碎模式

3.1 Fracture Editor 的工作流程

UE5 的 Fracture Editor 集成在 Geometry Collection 编辑器里。打开资产后,右侧 Fracture 面板提供 Uniform、Clustered、Radial、Planar、Slice 等破碎模式。

一个典型的工作流如下:

flowchart LR
    A["导入 Static Mesh"] --> B["生成基础凸包"]
    B --> C["选择破碎模式"]
    C --> D["设置 Voronoi 单元数"]
    D --> E["预览碎片分布"]
    E --> F{是否满足策划需求}
    F -->|"否"| G["调整噪声与偏置"]
    G --> D
    F -->|"是"| H["保存 Geometry Collection"]
    H --> I["拖入关卡测试"]

3.2 常用破碎模式

Uniform Voronoi:把模型切成大小相近的凸包,适合砖墙、石板。单元数越多,碎片越小,运行时开销越高。

Clustered Voronoi:先生成少量大碎片,再在大碎片内部继续细分。这样爆炸时先裂成大块,大块再碎成小片,视觉上更接近真实材料。后面会专门讲 Cluster 层级。

Radial:以某一点为中心向外放射状破碎,非常适合爆炸点、子弹冲击。Radial 可以设置衰减半径和角度噪声,让裂痕不那么规整。

Planar / Slice:用平面切分模型,适合做楼板断裂、玻璃碎裂。Slice 可以指定多个切片方向和间距。

Custom:从外部 DCC(如 Houdini)导出预切分的网格,再导入成 Geometry Collection。这种模式能得到艺术方向最可控的破碎效果,但流程更重。

3.3 破碎质量与凸包近似

Chaos 运行时只能处理凸包碰撞。碎片的视觉形状可以很复杂,但物理碰撞会用 Convex Decomposition 近似。如果碎片太细长或者凹陷严重,Convex Hull 会把缝隙填掉,导致碎片之间穿插。Fracture Editor 允许设置 Convex Can SplitFraction Amount,在凸包数量和碰撞精度之间取舍。

数学上,一个刚体的线性动量满足:

F=mdvdt\mathbf{F} = m \frac{d\mathbf{v}}{dt}

角运动则由力矩和惯性张量决定:

\boldsymbol{\tau} = \mathbf{I} \cdot \frac{d\boldsymbol{\omega}}{dt}

Chaos 对每个碎片都积分这两个方程。碎片数量 NN 直接决定每帧的刚体数量级,而刚体碰撞对的复杂度大致是 O(N2)O(N^2) 在最坏情况下。所以破碎不是越细越好。

四、Cluster 与层级破碎

4.1 为什么需要 Cluster

一面墙如果一次性碎成 500 块,每一小块都是独立刚体。玩家离得很远时,根本看不清细节,却还要支付 500 个刚体的积分和碰撞开销。Cluster 把碎片组织成树状层级,父节点在受力较小时保持为一个整体运动,只有受力超过阈值才裂成子节点。

graph TD
    A["整面墙 Root"] --> B["左上区域 Cluster"]
    A --> C["右上区域 Cluster"]
    A --> D["底部区域 Cluster"]
    B --> B1["碎片 1"]
    B --> B2["碎片 2"]
    B --> B3["碎片 3"]
    C --> C1["碎片 4"]
    C --> C2["碎片 5"]
    D --> D1["碎片 6"]
    D --> D2["碎片 7"]

这种结构和八叉树或者 Bounding Volume Hierarchy 类似,核心思想是用空间聚合减少同时活跃的刚体数量。

4.2 Cluster 的参数

Fracture Editor 里控制 Cluster 的参数主要有:

  • Cluster Level:层级深度。设为 2 表示先分几大块,每块再分几小组。
  • Cluster Size:每个父节点下平均包含多少子碎片。
  • Cluster Noise:让 Cluster 边界不规则,避免规则切块。
  • Anchor on Geometry:把某些 Cluster 固定在不可移动的位置,比如墙和地面接缝处。

Cluster 在运行时的解聚规则由 Field System 或破坏事件触发。默认情况下,Chaos 会根据连接强度判断 Bond 是否断裂。一个 Bond 的强度可以设为 ss,当 Field 施加的应变超过 ss 时断开。

4.3 石柱坍塌案例

假设场景中有一根古希腊风格的石柱,高 3 米,材质是大理石。策划要求玩家用锤子敲击柱身时,石柱从敲击点开始出现放射状裂纹,然后断裂成三段,最后倒塌砸到地面碎成若干小块。

做法是把石柱做成三层 Cluster:

  1. 第一层:整根石柱分为上、中、下三段。
  2. 第二层:每一段再分成 8 到 12 个中等碎片。
  3. 第三层:每个中等碎片内部用 Uniform Voronoi 细分为 4 到 6 个小碎片。

敲击时 Field System 在命中点施加 Radial 力场,先打断根节点的 Bond,三段分离;中段坍塌触地时与地面碰撞产生冲击 Field,触发第二层 Cluster 解聚;碎片反弹时再继续细分。视觉上从小到大,物理上从粗到细,开销被摊平在时间轴上。

五、Field System 控制破坏

5.1 Field 是什么

Field System 是 UE5 中一种运行在 CPU 上的体积场,用来驱动 Chaos 破坏、布料、Niagara 等系统。Field 由若干 Field Node 组合而成,常见的 Node 类型包括:

  • Radial Vector:从中心向外推的径向力,爆炸、冲击波都用它。
  • Radial Intensity:径向标量场,常用来控制破碎强度或质量缩放。
  • Uniform Vector:恒定方向力,比如风吹、重力异常。
  • Wave:随时间衰减的波动场,适合做震动、余波。
  • Box / Cylinder / Sphere:限定场的空间形状。

这些 Node 通过 Field System Component 或 Blueprint 在运行时生成,并叠加到 Geometry Collection 的 GeometryCollectionComponent 上。

5.2 Field 的工作时序

当玩家发射火箭筒,弹着点产生爆炸 Field,系统会按下面的顺序处理:

sequenceDiagram
    participant Player as "玩家输入"
    participant WPN as "武器蓝图"
    participant FS as "Field System"
    participant GC as "Geometry Collection"
    participant Chaos as "Chaos 物理线程"

    Player->>WPN: 扣下扳机
    WPN->>FS: 在命中点生成 Radial Field
    FS->>GC: 采样场强到每个碎片
    GC->>Chaos: 标记 Bond 断裂与初始速度
    Chaos->>Chaos: 积分刚体运动
    Chaos->>GC: 更新碎片 Transform
    GC->>WPN: 返回破坏事件(可选)

5.3 Field 与 Cluster 的配合

Field 强度需要超过 Cluster 的阈值才会让父节点解聚。阈值太低会导致整面墙被一颗子弹打塌,太高则玩家觉得破坏没反馈。策划一般会反复试调以下数值:

  • Field 的 Magnitude MM
  • 衰减半径 RR
  • 碎片抗断阈值 TT
  • Cluster 层级的 Strain Threshold

一个简化的判定是:碎片受到的等效应变 ε\varepsilon 如果满足

ε>TMf(r,R)\varepsilon > \frac{T}{M} \cdot f(r, R)

其中 f(r,R)f(r, R) 是随距离衰减的函数,通常取 1/(1+r2/R2)1 / (1 + r^2 / R^2)。Chaos 内部实际计算更复杂,但这个公式足够理解参数之间的比例关系。

六、性能预算与实例限制

6.1 破坏系统的开销来源

Geometry Collection 在运行时的主要开销包括:

  1. 刚体积分:每个 Dynamic 碎片每帧都要积分线速度和角速度。
  2. 碰撞检测:碎片之间、碎片与场景之间的 Broad Phase 和 Narrow Phase。
  3. 断裂判断:遍历 Bond,根据 Field 和碰撞更新连接状态。
  4. 同步复制:联网时需要把碎片位置和事件同步到客户端。
  5. 渲染:每个碎片是独立 Mesh Section,Draw Call 会上升。

单机 Demo 里堆 5000 个碎片可能还能跑,到了复杂关卡、多玩家联机、主机平台,这个数字可能要压到几百。

6.2 常用的预算手段

减少碎片总量:只在玩家能近距离观察的区域做高密度破碎,远景用低模或者预烘焙动画替代。

使用 Cluster:把同时活跃的刚体数量控制在预算内。Cluster 是性价比最高的优化手段。

限制同时破碎数量:在 Chaos 物理设置里可以调整 Max Cluster LevelMax ChildrenMax Count。超出预算的碎片进入 Sleeping 或者被裁剪。

降低碰撞精度:把 Collision Type 从 Full 改成 Shard,或者用简化的凸包。石柱倒塌时远端碎片没人会盯着看,用便宜碰撞完全可行。

Sleeping 与 Deactivation:长时间不动的碎片自动进入 Sleep,停止积分和碰撞,直到再次受力。Chaos 的 Collision Impulse Wake 可以在新力到达时重新唤醒。

异步物理线程:UE5 默认把 Chaos 放到单独物理线程,主线程不会等待物理步。可以开启 bSubsteppingbUseFixedBrd 来稳定大质量比物体的模拟。

调试性能时可以在控制台输入 stat chaos,查看当前活跃的刚体数、碰撞对数和物理线程耗时。Chaos Visualizer 也能把每个碎片的碰撞凸包、Bond 连接、Sleeping 状态画在视口里,方便定位是哪块 Geometry Collection 在拖慢帧率。

七、破坏事件与 Gameplay 联动

破坏不能只停留在视觉效果上,还需要告诉游戏逻辑:这面墙塌了、这条路被堵住了、这个掩体不能用了。Geometry Collection 组件会派发多种事件,Blueprint 和 C++ 都可以监听。

7.1 常用事件

  • OnChaosBreakEvent:Bond 断裂时触发,返回断裂位置和碎片索引。
  • OnChaosCollisionEvent:碎片与其他物体碰撞时触发,包含碰撞点和冲量。
  • OnChaosCrumblingEvent:Cluster 解聚时触发,用于区分大结构解体和小碎片脱落。
  • OnChaosRemovalEvent:碎片被移除或进入 Sleeping 时触发。

事件参数里通常包含 TransformIndexLocationVelocityMass。策划可以根据这些信息决定要不要播放音效、生成粒子、扣血、打开通路。

7.2 一个 Blueprint 示例

下面是一个简化的事件处理逻辑,当石柱顶部碎片触地时,检测冲量是否足够大,足够则播放灰尘粒子并通知任务系统:

Event OnChaosCollisionEvent
    For Each Collision
        If Collision.Location.Z < 100.0
            And Collision.Velocity.Size() > 500.0
        Then
            Spawn Emitter at Location
            Broadcast "PillarToppled"
        End
    End

C++ 里对应的写法类似这样:

void APillarActor::BeginPlay()
{
    Super::BeginPlay();
    if (GeometryCollectionComp)
    {
        GeometryCollectionComp->OnChaosCollisionEvent.AddDynamic(
            this, &APillarActor::HandleCollision);
    }
}

void APillarActor::HandleCollision(
    const FChaosPhysicsCollisionInfo& CollisionInfo)
{
    if (CollisionInfo.Location.Z < 100.0f
        && CollisionInfo.Velocity.Size() > 500.0f)
    {
        UGameplayStatics::SpawnEmitterAtLocation(
            GetWorld(), DustFX, CollisionInfo.Location);
        OnPillarToppled.Broadcast();
    }
}

注意监听大量碎片的碰撞事件会产生很多回调。如果关卡里有十几面可破坏墙,每面都监听所有碎片,主线程会被事件淹没。建议只在关键碎片上监听,或者按总质量过滤。

八、网络同步

8.1 Chaos 破坏的联网难题

破坏系统在多人游戏里是个老大难问题。几百个碎片的位置、速度、旋转如果每帧都同步,带宽根本吃不消。而且客户端和服务器物理模拟略有差异,碎片堆积的位置可能不一样,导致玩家看到不同的掩体高度。

UE5 对 Geometry Collection 提供了几种同步方案:

  • Server Authoritative:服务器模拟,客户端只接收位置和旋转。一致性最好,带宽消耗最大。
  • Client Predict + Server Correct:客户端先本地预测,服务器定期校正。手感好,但校正时可能出现碎片瞬移。
  • Event Driven Replication:只同步触发事件,比如爆炸 Field 和断裂位置。客户端用相同的种子本地回放破碎过程。带宽最低,但 determinism 要求极高。

8.2 推荐的联网策略

对于大部分射击或动作游戏,折中方案是 Event Driven 加关键状态校正:

  1. 服务器判定爆炸命中,广播 Field 参数和命中点。
  2. 所有客户端在相同位置应用相同 Field,Chaos 用固定时间步本地积分。
  3. 服务器定期采样少量代表碎片的位置,发送给客户端校正。
  4. 客户端用平滑插值把偏离的碎片拉回服务器位置。

要提升 determinism,可以:

  • 关闭浮点不确定性来源,比如随机初始速度、非确定性碰撞响应。
  • 使用 Fixed Time Step 物理更新。
  • 对 Chaos 使用 Deterministic Mode(在物理设置中开启)。
  • 限制 Fragment 总数,减少蝴蝶效应。

8.3 Network Prediction 与 gameplay 影响

破坏会影响关卡通行性。如果服务器和客户端对一面墙是否完全倒塌判断不一致,玩家客户端显示能走过去,服务器却认为还被挡住,就会出现橡皮筋拉扯。解决方式是在 Gameplay 层面用一个独立状态机记录结构完整性:

Integrity = 1.0 - (BrokenBondCount / TotalBondCount)
If Integrity < 0.3
    Enable NavMesh 缺口
    Replicate 结构状态到客户端

这样玩家看到的是视觉破坏,真正决定能不能通行的是这个轻量状态,而不是逐个碎片的物理位置。

九、UE5.8 破坏系统改进

9.1 编辑器工作流优化

UE5.8 在 Fracture Editor 里增加了更直观的 Voronoi 预览,破碎模式参数支持非破坏性编辑,可以随时回退到上一步。以前调整一次破碎要重新生成整个资产,现在可以在层级面板里单独重新生成某一层 Cluster。

9.2 性能与可扩展性

5.8 对 Chaos 的 Broad Phase 做了多线程优化,碎片数量较多时 CPU 占用更平稳。GeometryCollectionComponent 增加了 MaxSimulatedLevel 运行时属性,允许根据距离动态切换 Cluster 层级。靠近玩家的碎片保持完整模拟,远处的碎片直接降成单一刚体或者 Sleeping。

9.3 程序化破坏支持

新版本中 Fracture Mode 可以直接在关卡编辑器里对任意 Static Mesh 进行程序化切分,而不用先转成 Geometry Collection 资产。策划可以快速在关卡里画一条裂缝,引擎自动生成并替换为可破坏版本。这对早期白盒阶段验证破坏玩法很友好。

9.4 材质与渲染

破坏后的内部截面在 5.8 里支持自动材质映射。之前碎片截面通常显示默认灰色,现在 Fracture Editor 可以为每个切割面指定 Interior Material,并单独控制 UV 缩放。混凝土墙炸裂后能看到粗糙的骨料截面,而玻璃断面会有镜面反光,视觉细节提升明显。另外截面法线方向的处理也更稳定,减少了碎片边缘出现黑边或闪烁的情况。

9.5 Field System 改进

Field System 新增了几种曲线衰减类型,包括指数衰减、线性衰减和自定义曲线。Radial Field 现在支持方向性爆炸,可以指定爆炸锥角和方向向量,让定向地雷、破片手雷的效果更真实。

十、结语

那面被火箭筒轰塌的墙、那根被锤子敲断的石柱,以及整片可破坏的废弃工厂,共同说明 Chaos 和 Geometry Collection 提供了一整套实时破坏方案。这套方案不是简单的网格切割,而是把几何、物理、Gameplay、网络、性能预算串在一起的系统工程。

实际开发中,最重要的是提前和策划、美术、程序一起定好破坏规则:哪些物体可以破坏、破碎到什么精度、事件如何影响玩法、联网同步到什么程度。把这些规则落实成 Cluster 层级、Field 参数、事件回调和同步策略,才能让玩家在扣下扳机的那一刻,看到一堵墙真实而可控地倒塌。破坏系统的价值,最终体现在玩家的手感与记忆之中。