Unity碰撞检测机制的原理(更新中...)

总是碰到关于碰撞的问题,今天实在忍不住了,来把它搞懂,不然听到八叉树,BSP什么的就怕可不行。
转自:http://www.manew.com/thread-102595-1-1.html

碰撞机制

最近做动态地形生成的时候,发现碰撞检测无效,于是查阅了相关资料,大体上把unity的检测流程弄清楚了
碰撞检测,就是检测两个物体是否相交,如果物体非常规则,比如球体,直接检测圆心距离是否小于半径和即可,计算量十分小,但是,如果物体不规则,比如一个角色,进行十分细致的碰撞检测就会变的十分困难,这时候,我们一般会用简单几何体去逼近复杂网格
在这里插入图片描述
如上图所示,我用4个圆去逼近一个多边形,注意,下层圆圆心位于根圆到顶点连线上,且圆心位于上层圆边上的,类比到3d空间也是如此,可以用球体去趋近网格,这里需要注意,凹多边形的逼近是难计算的,所以内部会将其拆分成多个凸多边形
在这里插入图片描述
现在,假如有两个物体,那么,我们只需要检测这两个物体是否相交即可,如果有3个物体a,b,c ,那么,我们要比较ab ac bc,如果有四个物体abcd,我们要比较ab ac ad bc bd cd,可见,有n个物体,我们要比较(n-1)+(n-2)……+(1)次,如果物体相当多,那么比较次数也会及其可怕
为了解决这个问题,unity里使用了**空间划分技术,**目前主流的划分技术有BSP,BHV,八叉树,四叉树
这几种算法都用到了树结构,下面分别简单介绍一下

BSP

BSP:BSP是一个二叉树结构,首先选定一个面作为根节点(一般会选两侧物体数量大致相同的面),然后遍历物体,如果物体在此面正面,将其加入到左子节点,如果在反面,加入到右子节点,如果和此面相交,加入左右两个子节点,之后,将左右子节点作为新的根节点进行递归
构建完成后,在检测时,只要检测同一叶子节点的所有物体就行了
在这里插入图片描述
这里注意,检测物体位于哪面一般使用长方体来进行近似的,大家用unity的时候可能也注意到,gameobject有width和height两个属性,这两个属性很可能是用来进行划分的

BHV

BHV:将相邻的物体放在一个圆内,检测时只要检测同一个圆内的
在这里插入图片描述

八叉树,四叉树

在这里插入图片描述
这两个其实原理相同,上面是四叉树,类比到3d空间就是八叉树

这时,我们可以发现,如果碰撞体位移了,或者碰撞网格改变了,树的结构也会随之变化,这里我猜测,unity内部会有静态和动态两种树,静态树时预先计算好的,而动态树则会在有物体位移时重新计算,而动态树很可能也有相关优化,比如子物体多的物体会单独维护一个树,再将其作为动态树的子树
而这里有个问题,物体位移时树是会改变的,碰撞不会出现问题。但碰撞网格在运行时改变的话,碰撞会失效,如果我们动态生成一个物体,为其加入网格碰撞器,那么,它仍然不会有碰撞检测,可能是由于树没有更新,也有可能逼近算法没有执行,解决办法是,生成物体后,调用Setactive(false),然后Setactive(true)
在OnEnable里,会调用函数生成对网格进行碰撞检测所需的信息
在这里插入图片描述

接下来说一下连续碰撞检测的问题,上图说明了不同collisiondectection的物体是否进行连续检测
连续检测算法大概有下面几种,
一,比如说某物体的位移随时间变化为y=vt
unity里每次检测相隔0.02s,那么,假如上帧时间为0,这帧时间为0.02,引擎可以将0.002,0.004,0.006……0.018,0.02分别带入方程,只要有一个检测到就说明有碰撞,但是unity里用的并不是这一种
二,计算量最小,从此帧到上帧的位置连一条线,检测这条线有没有碰撞检测
三,unity里很可能就是这种,因为文档里说,连续检测只适用于内置的
在这里插入图片描述
此方法将物体的轨迹视为一个碰撞体进行检测,比如
在这里插入图片描述
将球体的轨迹近似为一个胶囊体,然后对胶囊体进行碰撞检测

  • 10
    点赞
  • 46
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值