类型:休闲益智
大小:61.18 MB
2026-09-22 20:07:02 k73游戏之家 作者:转载
做Unity项目的人早晚都会碰到Collider Shapes这个坎。不管是做FPS、RPG还是简单的物理小游戏,只要场景里有物体需要碰撞检测,就绕不开碰撞体形状的选择。《Collider Shapes》说白了就是告诉引擎“这个物体的碰撞范围长什么样”,听起来简单,实际用起来坑特别多。我刚开始做项目那会儿,给所有模型都挂Mesh Collider,结果帧率直接掉到个位数,后来才明白碰撞体形状选不对,优化全白费。今天就把我踩过的坑和后来总结的经验一次性讲清楚,希望能帮到正在纠结碰撞体形状的朋友。
Unity里自带的碰撞体形状就那么几种,盒体、球体、胶囊体、网格、地形,每个都有自己的脾气。盒体碰撞体是最省性能的,计算量小,适合箱子、墙壁、地板这些方方正正的东西。球体碰撞体适合滚动的球、角色头部、爆炸范围检测,它的碰撞检测特别快,因为球体数学计算简单。胶囊体是角色控制器的标配,因为它能很好地贴合人体形状,上下楼梯、贴墙滑动都不会卡住。
网格碰撞体最坑,它是根据模型网格生成的,精度高但性能开销巨大。很多人觉得模型长什么样就用什么碰撞体最准确,结果一个复杂场景几百个网格碰撞体,手机直接烫得能煎鸡蛋。我的建议是能不用网格碰撞体就不用,实在需要精确碰撞的地方,比如角色踩在凹凸不平的地形上,可以考虑用多个简单形状拼一个复合碰撞体来近似。
地形碰撞体是专门给Terrain用的,如果你用Unity的地形系统,直接加Terrain Collider就行,它内部有优化,比网格碰撞体好很多。选形状的核心原则就一条:能用简单形状就别用复杂形状,能合并就别拆开。你想想,玩家在游戏里跑动的时候,物理引擎每秒要算几十次碰撞检测,每个复杂形状都是负担。
有些朋友会问,那我的模型是个花瓶,用盒体碰撞体不是会穿模吗?确实会,但你要权衡。玩家真的会去摸花瓶的每个弧度吗?大多数情况下,一个盒体碰撞体加一个球体碰撞体组合起来,玩家根本感觉不到差别。除非是做VR那种需要精细交互的项目,普通游戏真没必要追求完美贴合。
性能优化这块,碰撞体形状的调整能带来非常明显的提升。第一招是给静态物体勾选Static,Unity会把它们的碰撞体合并成一颗大的静态碰撞树,查询速度快很多。很多新手不知道这个选项,场景里几百个静态箱子每个都单独算碰撞,白白浪费性能。勾上Static之后,物理引擎会预处理这些碰撞体,运行时开销几乎为零。
第二招是调整碰撞体的层级和层碰撞矩阵。Unity默认所有层之间都会互相检测碰撞,但你的子弹根本不需要和装饰品碰撞,UI触发器也不需要和地板碰撞。在Project Settings的Physics里把不需要的层对勾掉,能省下大量无用的碰撞检测。我做过一个测试,一个中等复杂度的场景,优化层碰撞矩阵之后物理开销直接降了四成,效果立竿见影。
第三招是给碰撞体加Rigidbody的时候注意Sleep Threshold。很多小物件碰撞后会一直抖动,物理引擎就一直在算,把Sleep Threshold调高一点,让它们快速进入休眠状态,能省不少CPU。不过要注意,休眠的物体被碰撞时会自动唤醒,所以不用担心它们不响应碰撞。
第四招是碰撞体的缩放。非均匀缩放的碰撞体在Unity里会有性能惩罚,尤其是球体和胶囊体被拉伸之后,物理引擎需要额外计算。尽量保持碰撞体缩放为1,需要调整大小就在建模软件里调好,或者在父节点上缩放,碰撞体本身别乱拉。
第五招是复合碰撞体的使用。一个物体需要多个碰撞体的时候,不要挂多个Collider组件,而是用一个Rigidbody加多个Collider作为子物体。这样物理引擎会把它们当作一个刚体来处理,效率更高。比如一辆车,可以用一个盒体做车身,四个球体做轮子,组合起来比一个网格碰撞体快得多。
第六招是碰撞体的Update频率。物理更新默认和Fixed Timestep绑定,一般是0.02秒一次。如果你的项目物理要求不高,可以适当调大Fixed Timestep,比如0.033秒,物理计算频率降低,CPU压力就小了。当然这会牺牲一些物理精度,具体数值要根据项目需求来平衡。
说几个我实际项目中常用的碰撞体搭配方案。角色控制器我一般用胶囊体碰撞体,半径0.3到0.5之间,高度1.8左右,配合Character Controller组件使用,移动起来很顺滑。角色身上再挂一个小的球体触发器用来检测拾取物品,这样拾取范围稍微比模型大一点,玩家体验更好。
子弹和抛射物用球体碰撞体,因为球体在高速运动时碰撞检测最稳定,不容易穿透。如果子弹速度特别快,还要把碰撞检测模式改成Continuous Dynamic,不然会直接穿过薄墙。这个坑我踩过好几次,明明瞄准了敌人却打不中,后来才发现是碰撞检测模式的问题。
场景建筑用盒体碰撞体,墙壁地板天花板都是盒体,组合起来就是一个完整的房间。如果墙面有斜角,可以用旋转的盒体来近似,或者用几个盒体拼一下。装饰物如果玩家碰不到,干脆不加碰撞体,省性能。需要碰撞的装饰物用球体或胶囊体包一下就行,不需要精确。
载具的话,车身用盒体,轮子用球体或者胶囊体。注意轮子的碰撞体要稍微比模型大一点,不然会陷进地面。悬挂系统可以用Wheel Collider,但那个比较吃性能,简单项目直接用球体加弹簧关节也能凑合。
地形方面,如果不用Unity自带地形,用网格模型做地面的话,可以用Mesh Collider但一定要勾选Convex,或者用多个盒体拼一个近似的地面。Convex会把网格碰撞体转换成凸包,性能好很多,但只适合凸形状的物体,凹形状的物体勾了Convex会变形。
最后说一个很多人忽略的点:碰撞体的中心点位置。碰撞体的Center偏移会影响物理计算,如果偏移太大,物体会出现奇怪的旋转和滑动。调整碰撞体的时候尽量让中心点靠近物体的几何中心,这样物理表现最自然。
碰撞体形状的优化不是一蹴而就的事,需要根据项目实际情况不断调整。我的经验是先把所有碰撞体都用最简单的形状代替,跑起来看效果,哪里不对再针对性优化。不要一开始就追求完美,先跑通再优化,这样效率最高。