61.性能优化-CPU-物理-避免复杂碰撞器类型
61.1 知识点
碰撞器性能消耗排行
Unity 自带碰撞器按性能消耗从低到高排序如下:
- 球体(Sphere Collider)
最省性能,数学公式简单。适合子弹、角色感知范围、球类等。 - 胶囊体(Capsule Collider)
稍比球复杂,仍为数学公式计算。常用于角色、NPC 碰撞体。 - 盒体(Box Collider)
稍复杂,但仍是矩阵与边界检测,性能较高。使用最广泛,如地板、墙壁、方形物体。 - 组合碰撞体
由多个 Sphere、Box、Capsule 拼接。开销比单一原始体略高,但仍远低于 Mesh Collider。 - 轮子碰撞器(WheelCollider)
主要开销来自垂直射线检测和摩擦、扭矩、制动相关计算。 - 地形碰撞体(Terrain Collider)
为地形系统优化的特殊碰撞器,内部使用高度图而非逐三角面,在大规模场景中比 Mesh Collider 高效很多。 - 网格碰撞器(Mesh Collider)
- 凸形(Convex)
Unity 将网格转为凸包,比凹形高效,但仍比原始体差很多。附带刚体时必须设为凸形。 - 凹形(Non-Convex)
直接对网格三角面做碰撞检测,性能最差,尤其高多边形模型。仅适合静态物体(地形、建筑)。
- 凸形(Convex)
- 布料(Cloth)
开销按 顶点数 × 约束迭代 ×(自/外部碰撞)计算。低顶点且无碰撞时成本可控,开启自碰撞/与 Collider 碰撞并提高迭代数后,成本迅速攀升。
尽量使用消耗更低的碰撞器,可节约性能。
示例:检查碰撞器类型
// 在 Editor 中检查物体是否使用了复杂碰撞器
Collider collider = GetComponent<Collider>();
if (collider is MeshCollider meshCollider)
{
if (!meshCollider.convex)
{
Debug.LogWarning($"物体 {gameObject.name} 使用凹形 Mesh Collider,性能开销较大");
}
}
不同碰撞器之间碰撞产生的消耗
当两个物体发生碰撞时(排除 WheelCollider 和 Cloth,它们属于不同的计算方式):
- 相同类型的简单碰撞体(Sphere、Capsule、Box)消耗最低
例如:Sphere-Sphere、Capsule-Capsule、Box-Box。 - 不同类型简单碰撞体 消耗略高,差别不大
例如:Sphere-Capsule、Sphere-Box、Capsule-Box。 - 简单碰撞体与 Mesh Collider
消耗取决于网格复杂度,三角面数越多,消耗呈指数级增加。
例如:Sphere-Mesh、Capsule-Mesh、Box-Mesh。 - 两个 Mesh Collider
消耗同样取决于网格复杂度,三角面数越多,呈指数级增加。
例如:Mesh-Mesh。
构建项目时,尽量让物体之间的碰撞器简单一致,尽量避免使用 Mesh Collider。
使用简单的网格碰撞器
使用 Mesh Collider 意味着更高开销,使用时建议遵守以下规则:
- 能不用就不用
可用多个 Box、Sphere、Capsule 拼凑成近似轮廓。 - 一定要用,先精简
尽量将复杂网格简化为简单网格,并优先设为凸网格。一般精度牺牲不会带来表现上的差别。
做法:让美术出低模网格、在 MeshCollider 中设置、或自己写相关工具。
避免复杂的物理组件
Terrain Collider、Cloth、WheelCollider 属于特殊用途组件,底层处理逻辑与常规碰撞器(Sphere、Box、Capsule)不同,计算量往往更大。若项目中没有对应需求,能不用就不用。
使用建议:
- Terrain Collider
只在使用 Unity 地形(Terrain)系统时用;普通场景地面用常规碰撞器更省。 - Cloth
只在近景、核心表现需要真实布料时才启用;其他情况用动画、Shader 替代。 - WheelCollider
真正做车辆时才用;简单小车、玩具效果用 Sphere、Raycast 即可。
61.2 知识点代码
Lesson61_性能优化_CPU_物理_避免复杂碰撞器类型.cs
public class Lesson61_性能优化_CPU_物理_避免复杂碰撞器类型
{
#region 知识点一 碰撞器性能消耗排行
//如果我们将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)
// 6-1.凸形碰撞器(Convex)
// Unity 会把网格转为凸包
// 比凹形高效一些,但依旧比原始体差很多
// 网格碰撞器附带刚体时必须设为凸形
// 6-2.凹形碰撞器(Non-Convex)
// 直接对网格三角面做碰撞检测
// 性能最差,尤其是高多边形模型
// 仅适合静态物体(地形、建筑)
//8.布料(Cloth)
// 与传统碰撞器不同,按布料顶点数量 × 约束迭代 ×(自/外部碰撞)进行开销
// 低顶点且无碰撞时成本可控,一旦开启自碰撞/与 Collider 碰撞并提高迭代数,成本迅速攀升
//我们应该尽量使用消耗更低的碰撞器
//可以节约性能
#endregion
#region 知识点二 不同碰撞器之间碰撞产生的消耗
//当两个物体发生碰撞时(排除 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
//在构建项目时,我们应该尽量让物体之间的碰撞器尽量简单一致
//尽量不要使用网格碰撞器
#endregion
#region 知识点三 使用简单的网格碰撞器
//通过前面的知识点我们知道
//使用网格碰撞器就意味着更高的开销,因此在使用网格碰撞器时应该遵守以下规则
//1.能不用就不用
// 可以用多个 Box、Sphere、Capsule 拼凑成近似轮廓
//2.一定要用,先精简
// 我们应该尽量将复杂网格碰撞器简化为简单网格碰撞器,并且优先设置为凸网格
// 一般这种精度牺牲并不会带来表现上的差别
// 做法:让美术出低模网格、在MeshCollider中进行设置、自己写相关工具
#endregion
#region 知识点四 避免复杂的物理组件
//地形碰撞器(TerrainCollider)、布料(Cloth)、轮子碰撞器(WheelCollider)
//这三类组件属于 特殊用途型 组件
//它们的底层处理逻辑如刚才所说,和常规碰撞器(Sphere、Box、Capsule)完全不同
//计算量往往更大,如果项目中没有对应的需求,我们应该能不用就不用!!
//什么时候使用它们:
//1.只在使用 Unity 地形(Terrain)系统时用;普通场景地面用常规碰撞器更省
//2.只在近景、核心表现需要真实布料(Cloth)时才启用;其他情况用动画、Shader 替代
//3.真正做车辆才用;简单小车、玩具效果用 Sphere、Raycast 就能搞定
#endregion
}
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com