UPL7-6——避免复杂碰撞体类型

碰撞器性能消耗排行

如果我们将 Unity 提供给我们的自带碰撞器进行性能消耗排行,那么得到的结果是这样的(前面的消耗更低,后面的消耗更高)

  1. 球体(Sphere Collider)

    最省性能,因为数学公式简单,适合用于子弹、角色感知范围、球类等

  2. 胶囊体(Capsule Collider)

    稍比球复杂,但依旧是数学公式计算,常用于角色、NPC 碰撞体

  3. 盒体(Box Collide)

    稍微复杂一点,但仍然是矩阵与边界检测,性能非常高,场景里使用最广泛,比如地板、墙壁、方形物体

  4. 组合碰撞体(由多个原始碰撞体(Sphere、Box、Capsule)拼接)

    开销比单一原始体略高,但仍远低于 网格碰撞器(Mesh Collider)

  5. 轮子碰撞体(WheelCollider)

    它的本质不是网格求交,主要开销来自于垂直射线检测和摩擦、扭矩、制动相关的计算

  6. 地形碰撞体(Terrain Collider)

    专门为地形系统优化的特殊碰撞器,内部使用高度图数据,而不是逐三角面,在大规模场景中比 Mesh Collider 高效很多

  7. 网格碰撞器(Mesh Collider)

    1. 凸形碰撞器(Convex)

      Unity 会把网格转为凸包,比凹形高效一些,但依旧比原始体差很多,网格碰撞器附带刚体时必须设为凸形

    2. 凹形碰撞器(Non-Convex)

      直接对网格三角面做碰撞检测,性能最差,尤其是高多边形模型,仅适合静态物体(地形、建筑)

  8. 布料(Cloth)

    与传统碰撞器不同,按布料顶点数量 × 约束迭代 ×(自/外部碰撞)进行开销
    低顶点且无碰撞时成本可控,一旦开启自碰撞/与 Collider 碰撞并提高迭代数,成本迅速攀升

我们应该尽量使用消耗更低的碰撞器,可以节约性能

不同碰撞器之间碰撞产生的消耗

当两个物体发生碰撞时(排除 WheelCollider​ 和 Cloth,因为他们严格意义上属于不同的计算方式)

  1. 相同类型的简单碰撞体(Sphere、Capsule、Box)性能消耗会更低

    比如:Sphere-Sphere, Capsule-Capsule, Box-Box

  2. 不同简单碰撞体(Sphere、Capsule、Box)性能消耗略高,但是差别并不会太大

    比如:Sphere-Capsule、Sphere-Box、Capsule-Box

  3. 如果简单碰撞体(Sphere、Capsule、Box)和网格碰撞体(Mesh Collider)产生碰撞

    性能消耗取决于网格复杂度,三角面数越多,性能消耗呈指数级增加
    比如:Sphere-Mesh Collider、Capsule-Mesh Collider、Box-Mesh Collider

  4. 如果两个网格碰撞体(Mesh Collider)产生碰撞

    性能消耗取决于网格复杂度,三角面数越多,性能消耗呈指数级增加
    比如:Mesh Collider-Mesh Collider

在构建项目时,我们应该尽量让物体之间的碰撞器尽量简单一致,尽量不要使用网格碰撞器

使用简单的网格碰撞器

通过前面的知识点我们知道,使用网格碰撞器就意味着更高的开销,因此在使用网格碰撞器时应该遵守以下规则

  1. 能不用就不用

    可以用多个 Box、Sphere、Capsule 拼凑成近似轮廓

  2. 一定要用,先精简

    我们应该尽量将复杂网格碰撞器简化为简单网格碰撞器,并且优先设置为凸网格,一般这种精度牺牲并不会带来表现上的差别
    做法:让美术出低模网格、在 MeshCollider 中进行设置、自己写相关工具

避免复杂的物理组件

地形碰撞器(TerrainCollider)、布料(Cloth)、轮子碰撞器(WheelCollider),这三类组件属于 特殊用途型 组件
它们的底层处理逻辑如刚才所说,和常规碰撞器(Sphere、Box、Capsule)完全不同
计算量往往更大,如果项目中没有对应的需求,我们应该能不用就不用!!

什么时候使用它们:

  1. 只在使用 Unity 地形(Terrain)系统时用;普通场景地面用常规碰撞器更省
  2. 只在近景、核心表现需要真实布料(Cloth)时才启用;其他情况用动画、Shader 替代
  3. 真正做车辆才用;简单小车、玩具效果用 Sphere、Raycast 就能搞定