物理引擎即描述真实世界中物理现象的算法,如刚体物理,软体物理和流体物理,unity本身支持的主要为刚体物理,我们也可以自己编写一些其它的模拟效果。
unity内置Nvidia开发的Physx引擎(3D)和一个开源引擎Box2D,它们是共存的但不能作用在同一个物体身上。
引擎的功能主要是1.碰撞检测 2.刚体动力学模拟
在unity中每一次物理更新会发生:
1.调用FixedUpdate
2.唤醒所以yield WaitForFixedUpdate的协程
3.执行物理事件:OnTriggerEnter等等
一般来说物理引擎会以一个固定的时间步长来对物理组件进行更新模拟。(FixedUpdate)
所以在高帧率下这可能会引起一些卡顿或不协调,于是unity会在每一渲染帧对物理行为进行插值来保证两次物理更新之间平滑过渡。
离散碰撞检测 Discrete Collision Detection
DCD是一种最基本的碰撞检测方式
DCD原理:
1.获取上一帧位置,速度等信息,并据此计算出新的位置与速度。
2.对于这些新位置,DCD会检测是否与其它物体重叠。
3.若有重叠,则进入碰撞物理计算并得出最后的速度与位置。
但是DCD有一个很大的问题就是快速移动会穿过其它物体,从而逃过碰撞检测,因为我们始终以固定时间步长来更新物理,所以有可能两个物体在前后两帧之间穿过了彼此,但物理引擎并不知情。
连续碰撞检测 Continuous Collision Detection
Sweep-base CCD:
原理:
1.记录下物体上一帧与当前帧的位置与线速度
2.利用这两帧的数据计算出一个移动范围
3.对该移动范围内的物体进行碰撞检测并进行相关的位置/速度更新
Sweep-base CCD是依赖线速度的一种算法,它并不能处理角速度较大时物体的碰撞,其次它极其消耗性能,尤其是扫过范围内物体较多时。
在unity中我们可以把Rigidbody组件的Collision Detection设为“Continuous”或者“Continuous Dynamic”来开启Sweep-base CCD。
Speculative CCD:
Speculative CCD会根据上一帧的数据来预测并扩大物体的矩形包围盒,在上图中引擎通过扩大包围盒来找到了n1和n2两个碰撞点的法线。于是引擎重新规划了小球即将到达的位置(t2)。
Speculative CCD对快速旋转的物体而言处理的比Sweep-base CCD要好,同样的我们也可以在unity中选择“Continuous Speculative”来开启Speculative CCD。
连接关节组件:Fixed Joint
Fixed Joint组件允许我们把一个刚体“粘”到另一个刚体上,也允许它们在一定力下断裂。
Hinge Joint
与Fixed Joint类似,不同的是Hinge Joint的行为是像门一样转动。
2D作用器(Effector2D)
给2D物体增加一些更复杂的行为。必须搭配Collider2D使用。
盒状射线检测 BoxCast:
BoxCast函数以origin为起点生成一个长宽为size,旋转角度为angle的矩形方块,并将其向direction方向投出distance的距离。接着BoxCast会返回接触到的物体信息。
更多的射线检测:
圆形:
胶囊:
射线检测可视化:
对于基本的RayCast可视化函数:
对于盒装射线,可以通过计算4个顶点的位置,再利用Debug.DrawLine来连起来即可。