关于Unity(rigidbody)碰撞穿透
首先,说说碰撞的条件:1.rigidbody(刚体),一般用在主动移动的物体上,比如角色。2.collider,碰撞器,一般用于受力物体上,比如障碍块。
物理的碰撞当然是基于物理检测计算,而这个计算是消耗cpu和gpu的,那么,碰撞穿透是什么鬼?
发生概率即触发方式:
1.刚体速度足够快,被撞物体的collider足够薄。
2.刚体速度在一定的v,被撞物体也在一定的速度v(被撞物体可移动)。
3.暂时未发现的其他情况。
在分析这两种(3种)情况之前,先了解下一个刚体(rigidbody)属性参数:Collision Detection(碰撞检测):
它有三种选项:Discrete(离散),Continuous(连续),Continuous Dynamic(动态连续),我们参考下官方的解释:
该属性用于控制避免高速运动的游戏对象穿过其他的对象而未发生碰撞,有三项可供选择
Discrete:离散碰撞器。该模式与场景中其他的所有碰撞体进行碰撞检测。该项为默认值。
Continuous:连续碰撞检测。该模式用于检测与动态碰撞体(带有Rididbody)的碰撞,使用连续碰撞检测模式来检测与网格碰撞体(不带ridigbody)碰撞。(添加一句原文翻译漏了),Rigidbody设置为连续动态碰撞检测模式将使用连续碰撞来检测。其他刚体会采用离散碰撞模式。此模式适用于那些需要与采用连续动态检测的对象相碰撞的对象。这对物理性能会有很大影响,如果不需要对快速运动对象进行碰撞检测,就使用离散碰撞检测模式。
Continuous Dynamic:连续动态碰撞检测模式,该模式用于检测与采用连续碰撞撞模式或连续
动态碰撞模式对象的碰撞,也可用于检测没有rigidbody的静态网格碰撞体。对于与之碰撞的其他对象可采用离散碰撞检测。动态连续碰撞检测模式也可用于检测快速运动的游戏物体。
翻译就是这样的理解并不难:后面两项就是为了用来能够检测到快速运动的物体不至于
你的void OnCollisionEnter(Collision hit)函数检测不到,而至于一个为Continuous Dynamic的刚体和一个Discrete的刚体碰撞,前者会使用使用Continous(连续)碰撞,后
者离散碰撞
再来总结下:当使用默认的离散式碰撞检测时,如果前一桢时对象在墙这一面,下一桢时对象已到到了墙另一面,那么碰撞检测算法将检测不到碰撞的发生,你可以将该对象的碰撞检测属性设置为Continuous,这时碰撞检测算法将会防止对象穿过所有的静态碰撞体,设置为Continuous Dynamic将还会防止穿过其他也设置为Continuous或者Continuous Dynamic的刚体。
这就很好理解,如果我们的主角在运动中碰到的都是静态collider,那么使用离散检测是可以满足的。如果我们在游戏中,主角将会碰撞到动态的collider,那么检测模式应该选择连续或者连续动态检测。这样可以很好的避免穿透现象。
然后,你以为这样就高枕勿忧了么?在实际的项目中,我们可能会发现,我们刚体上已经选择了连续检测甚至连续动态检测,依旧会有穿透问题,这就是我上面列举的两条(3条),被碰撞体的碰撞器太薄,被碰撞体的速度太快。这样依旧会导致穿透,那么原理是什么?我们知道unity中有fixedupdate,update这些更新方法,而这些更新中,都是有时间间隔更新的,更新的时候是用基础速度*时间,很有可能这个结果计算出来的时候车已经冲过了被碰撞体,就导致了我们的角色穿透,或者卡在被碰撞器的里面。
so,知道了这些,我们在项目中就知道如何规避这些所谓的“bug”了。
by优三帝同学 2015.9.13