碰撞检测问题及解决

在Unity3D中,碰撞可以形象理解为现实世界中的碰撞,并且由于物理引擎的模拟,使碰撞物体也会如现实世界一样产生相同的碰撞结果,如运动轨迹的改变、反弹等,总之碰撞的结果为产生我们不期望的物体运动行为。为了避免产生这种碰撞,就需要进行碰撞检测。

碰撞检测实现一

碰撞检测的原理是在物体移动的前方放置一个虚拟物体,它与物体进行同步运动。如果有障碍,则要先与虚拟物体碰撞。一旦检测到虚拟物体的碰撞,则运动物体停止移动。

  • 实现时则是使用虚拟射线来进行检测,检测时使用到的api分别如下截图:

clip_image002

图 - 1 Physic.Raycast射线扫描API

  • 碰撞检测的具体实现如下截图:

clip_image004

图 - 2 碰撞检测

  • 碰撞检测的调用实现如下截图:

clip_image005

图 - 3 调用碰撞的实现

实现一的问题及分析

以上实现经过分析,原理想法上没问题,就是每隔一个固定频率后进行射线碰撞检测。但是效果上却总是会在一些偶然的情况下发生碰撞,具体情形如下截图:

clip_image006

图 - 4 碰撞导致不期望的运动

  •  Update受制于FPS问题

经过分析,发现update虽然是每帧执行的,但是Unity3D的FPS——每秒的帧数,是变化的,它的值取决于渲染场景的面数;渲染速度又受机器的性能特别是CPU、内存、显卡不同而表现很大的差异。如果场景中渲染的面数太多,并且机器配置不够好,可能导致FPS很低,从而使渲染的两帧之间时间间隔很大,而在这个间隔内,碰撞已经发生,从而出现了上面的碰撞现象。

对于物理运动中需要进行固定频率的动作,Unity3D提供了FixedUpdate方法,这个频率是系统参数,可以更改。因此,我们使用FixedUpdate来替换Update可解决此问题。

  •  射线检测问题

如图 - 2 碰撞检测实现中,虽然多加了几条射线,但毕竟只是物体中的个别点。在我们的场景中,物体都是规则的且正常运动规律显著,所以只需要把几个特征点找到然后分别进行射线检测即可。但是这个毕竟是存在缺陷的,如果能够对物体整个面进行检测,那就完美了。

幸运的是,自Unity3D 版本3以来,针对刚体的碰撞检测问题,专门提供了Rigidbody.SweepTest方法。需要注意的是Physics.Raycast里面有一个层的概念,而且不是必须刚体才会被检测到;而Rigidbody.SweepTest则只检测刚体碰撞,与层无关。

碰撞检测的改善性实现

经过以上分析,可以知道碰撞检测会用到关键性方法Rigidbody.SweepTest,它的API如下截图:

clip_image008

图 - 5 刚体碰撞检测的API

改善后的实现如下截图:

clip_image009

图 - 6 改善性实现代码

经过试验,改善后的实现可以很好解决碰撞问题

转载于:https://www.cnblogs.com/huntdream/archive/2013/03/24/2978111.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值