碰撞检测问题及解决
2013-03-24 08:26
253 查看
在Unity3D中,碰撞可以形象理解为现实世界中的碰撞,并且由于物理引擎的模拟,使碰撞物体也会如现实世界一样产生相同的碰撞结果,如运动轨迹的改变、反弹等,总之碰撞的结果为产生我们不期望的物体运动行为。为了避免产生这种碰撞,就需要进行碰撞检测。
实现时则是使用虚拟射线来进行检测,检测时使用到的api分别如下截图:
图 - 1 Physic.Raycast射线扫描API
碰撞检测的具体实现如下截图:
图 - 2 碰撞检测
碰撞检测的调用实现如下截图:
图 - 3 调用碰撞的实现
图 - 4 碰撞导致不期望的运动
Update受制于FPS问题
经过分析,发现update虽然是每帧执行的,但是Unity3D的FPS——每秒的帧数,是变化的,它的值取决于渲染场景的面数;渲染速度又受机器的性能特别是CPU、内存、显卡不同而表现很大的差异。如果场景中渲染的面数太多,并且机器配置不够好,可能导致FPS很低,从而使渲染的两帧之间时间间隔很大,而在这个间隔内,碰撞已经发生,从而出现了上面的碰撞现象。
对于物理运动中需要进行固定频率的动作,Unity3D提供了FixedUpdate方法,这个频率是系统参数,可以更改。因此,我们使用FixedUpdate来替换Update可解决此问题。
射线检测问题
如图 - 2 碰撞检测实现中,虽然多加了几条射线,但毕竟只是物体中的个别点。在我们的场景中,物体都是规则的且正常运动规律显著,所以只需要把几个特征点找到然后分别进行射线检测即可。但是这个毕竟是存在缺陷的,如果能够对物体整个面进行检测,那就完美了。
幸运的是,自Unity3D 版本3以来,针对刚体的碰撞检测问题,专门提供了Rigidbody.SweepTest方法。需要注意的是Physics.Raycast里面有一个层的概念,而且不是必须刚体才会被检测到;而Rigidbody.SweepTest则只检测刚体碰撞,与层无关。
图 - 5 刚体碰撞检测的API
改善后的实现如下截图:
图 - 6 改善性实现代码
经过试验,改善后的实现可以很好解决碰撞问题
碰撞检测实现一
碰撞检测的原理是在物体移动的前方放置一个虚拟物体,它与物体进行同步运动。如果有障碍,则要先与虚拟物体碰撞。一旦检测到虚拟物体的碰撞,则运动物体停止移动。实现时则是使用虚拟射线来进行检测,检测时使用到的api分别如下截图:
图 - 1 Physic.Raycast射线扫描API
碰撞检测的具体实现如下截图:
图 - 2 碰撞检测
碰撞检测的调用实现如下截图:
图 - 3 调用碰撞的实现
实现一的问题及分析
以上实现经过分析,原理想法上没问题,就是每隔一个固定频率后进行射线碰撞检测。但是效果上却总是会在一些偶然的情况下发生碰撞,具体情形如下截图:图 - 4 碰撞导致不期望的运动
Update受制于FPS问题
经过分析,发现update虽然是每帧执行的,但是Unity3D的FPS——每秒的帧数,是变化的,它的值取决于渲染场景的面数;渲染速度又受机器的性能特别是CPU、内存、显卡不同而表现很大的差异。如果场景中渲染的面数太多,并且机器配置不够好,可能导致FPS很低,从而使渲染的两帧之间时间间隔很大,而在这个间隔内,碰撞已经发生,从而出现了上面的碰撞现象。
对于物理运动中需要进行固定频率的动作,Unity3D提供了FixedUpdate方法,这个频率是系统参数,可以更改。因此,我们使用FixedUpdate来替换Update可解决此问题。
射线检测问题
如图 - 2 碰撞检测实现中,虽然多加了几条射线,但毕竟只是物体中的个别点。在我们的场景中,物体都是规则的且正常运动规律显著,所以只需要把几个特征点找到然后分别进行射线检测即可。但是这个毕竟是存在缺陷的,如果能够对物体整个面进行检测,那就完美了。
幸运的是,自Unity3D 版本3以来,针对刚体的碰撞检测问题,专门提供了Rigidbody.SweepTest方法。需要注意的是Physics.Raycast里面有一个层的概念,而且不是必须刚体才会被检测到;而Rigidbody.SweepTest则只检测刚体碰撞,与层无关。
碰撞检测的改善性实现
经过以上分析,可以知道碰撞检测会用到关键性方法Rigidbody.SweepTest,它的API如下截图:图 - 5 刚体碰撞检测的API
改善后的实现如下截图:
图 - 6 改善性实现代码
经过试验,改善后的实现可以很好解决碰撞问题
相关文章推荐
- SpriteKit:开启物理逐像素(Per-Pixel)碰撞检测后发现的问题及解决(续)
- SpriteKit:开启物理逐像素(Per-Pixel)碰撞检测后发现的问题及解决(续)
- JAVA学习日志 坦克游戏 解决了对象数组的问题,检测碰撞,随机下落速度,计时,线程终止
- unity解决快速运动物体碰撞检测穿透问题
- SpriteKit:开启物理逐像素(Per-Pixel)碰撞检测后发现的问题及解决
- SpriteKit:开启物理逐像素(Per-Pixel)碰撞检测后发现的问题及解决
- SpriteKit:开启物理逐像素(Per-Pixel)碰撞检测后发现的问题及解决
- SpriteKit:开启物理逐像素(Per-Pixel)碰撞检测后发现的问题及解决(续)
- MFC 简单内存泄漏检测方法,解决Detected memory leaks!问题
- 碰撞检测:圆的碰撞运动,关键在于碰撞后速度的分解问题
- androidstudio检测代码内的中文字符(解决安卓国际化修改字符问题)
- 解决Android编辑框在全屏模式下无法检测布局变化的问题
- unity3d刚体和碰撞检测学习一:新建一个plane和一个sphere,却碰撞检测失败的问题
- XP CPU经常莫名其妙60%-70%,HDTune检测无坏块,System Interrupts进程异常问题解决
- Win7系统经常弹出“Windows检测到一个硬盘问题”提示窗口的故障原因及解决方法
- 检测到 ContextSwitchDeadlock 问题的解决办法!
- Ubuntu 12.04 经常弹出"检测到系统程序出现问题"解决方法
- Oracle安装出现 安装检测到系统的主IP地址是DHCP分配的地址 及 无法与该代理取得联系。请验证此代理的 url 是否为 null 问题解决
- “Visual Studio .NET 已检测到指定的 Web 服务器运行的不是 ASP.NET 1.1 版...”问题的解决办法
- 解决双系统问题,先安装win7,再安装ubuntu,发现ubuntu不能识别检测已经安装的win7,并且只能看到一整块硬盘的问题