要产生碰撞必须为游戏对象添加刚体(Rigidbody)和碰撞器,刚体可以让物体在物理影响下运动。碰撞体是物理组件的一类,它要与刚体一起添加到游戏对象上才能触发碰撞。如果两个刚体相互撞在一起,除非两个对象有碰撞体时物理引擎才会计算碰撞,在物理模拟中,没有碰撞体的刚体会彼此相互穿过。
物体发生碰撞的必要条件:
两个物体都必须带有碰撞器(Collider),其中一个物体还必须带有Rigidbody刚体。
在unity3d中,能检测碰撞发生的方式有两种,一种是利用碰撞器,另一种则是利用触发器。
碰撞器:包含了很多种类,比如:Box Collider(盒碰撞体),Mesh Collider(网格碰撞体)等,这些碰撞器应用的场合不同,但都必须加到GameObjecet身上。
触发器:只需要在检视面板中的碰撞器组件中勾选IsTrigger属性选择框。如果既要检测到物体的接触又不想让碰撞检测影响物体移动或要检测一个物件是否经过空间中的某个区域这时就可以用到触发器
例子:
- 碰撞器:汽车被撞飞、皮球掉在地上又弹起效果
- 触发器:人站在靠近门的位置门自动打开效果
Unity3d中的碰撞器和触发器的区别:
碰撞器是触发器的载体,而触发器只是碰撞器身上的一个属性
当Is Trigger=false时,碰撞器根据物理引擎引发碰撞,产生碰撞的效果,可以调用OnCollisionEnter/Stay/Exit函数;
当Is Trigger=true时,碰撞器被物理引擎所忽略,没有碰撞效果,可以调用OnTriggerEnter/Stay/Exit函数。
Static Colliders 静态碰撞器
指的是没有附加刚体而附加了碰撞器的游戏对象。这类对象会保持静止或者很轻微的移动。对于环境模型十分好用,当和刚体碰撞时而不会移动。
不要逐帧移动一个静态碰撞器,移动静态碰撞器将导致PhysX引擎的内部重置,非常耗费资源,而且会造成性能的极大下降。
Rigidbody Collider 刚体碰撞器
指的是同时附加了刚体和碰撞器的游戏对象。完全受物理引擎的影响,可以和只包含碰撞器的游戏对象碰撞。它将会成为你游戏中使用物理效果的基本类型碰撞器。
基于一个静态碰撞器唤醒其他刚体的行为是未定义的,而且移动静态碰撞器将不会对碰到它的刚体施加摩擦力。取而代之的是,要移动的碰撞器要保持是运动学刚体。
也就是说——
当用移动的静态碰撞器碰撞静止的刚体碰撞器时,是没有任何碰撞效果的,这是因为添加了Rigdbody的正方体是静止的,而静止的刚体会进入休眠。
刚体休眠:例如,当一个正方体掉到地板上静止后就会进入刚体休眠。刚体休眠完全自动发生,只要刚体的速度低于sleepAngularVelocity和sleepVelocity,该刚体就会开始休眠。处于休眠状态中的刚体,不会再对其进行碰撞检测和模拟,这会节约大量的CPU开销。
如何唤醒已经休眠了的刚体呢?有以下几种情况:
- 被施加了外力,也就是说在代码里使用了AddForce;
- 刚体的属性发生了变化;
- 和它通过关节连接的刚体发生了移动,因为连带关系,所以它也被唤醒了;
- 被其他刚体碰撞器碰撞。但是,只有处于运动状态中的刚体(包括普通的刚体碰撞器和运动学刚体碰撞器)能唤醒休眠中的刚体,静态碰撞器不能唤醒休眠中的刚体。
Kinematic Rigidbody Collider 运动学刚体碰撞器
指的是同时包含碰撞器和刚体,并且激活IsKinematic的一类游戏对象。要移动这类游戏对象,要修改它的Transform组件(指的是position和rotation这类属性),而不是用力。它们很像静态碰撞器,不过如果你想要不停地到处移动碰撞器,它们会更好用。这类游戏对象还有许多其他的独特使用情景。
运动学刚体碰撞器是个非常懒惰和霸道的家伙,它碰到其他碰撞器完全没有反应(其实还是有点反应,会触发一些碰撞函数的)。它不受力、重力或扭矩的影响。可以通过设置Transform 的position和rotation来准确的操作它们或者让它们动起来,但是,它们可以和其他的非运动学刚体互相作用。对于放在运动学刚体碰撞器上面的刚体,会受到运动学刚体施加的摩擦力。
Character Controllers 角色控制器
如果想制作一个类似人的角色那就使用角色控制器。这可以是第三人称平台游戏、第一人称射击游戏的主要角色或任何敌对角色。
角色控制器不受力影响(但是重力效果还是有的)但是可以被由代码施加的力推动。通常,所有类似人的角色都用角色控制器来执行。
角色控制器本身不具物理特性,因此如果想应用真正的物理作用——在绳上摇摆,被大石头推动——到你的角色,必须用刚体,这会允许你把铰链或力用到你的角色上。
角色控制器永远沿Y轴对齐,因此,如果你的角色需要在空间中改变方向那也必须用到刚体(比如在变化的引力控制下)。但是,要意识到调整一个刚体在角色上表现自然是很难的,因为游戏角色自身的非物理特性总想表现出来。另一个困难是,角色控制器可以从特定高度的台阶上平滑地滑下,而刚体不会。
如果想让角色控制器推开其他刚体或者对象,你可以在对象附加的脚本中添加OnControllerColliderHit()函数,这样对它们施加力就能够产生碰撞。
也就是说,角色控制器可以使用物理效果影响其他对象,前提是你自己写了脚本。
而角色控制器不能通过物理效果被其他对象影响。因此,如果你想让你的游戏角色被物理效果影响,那就最好使用刚体而不是角色控制器。
Layer-Based Collision Detection 基于层的碰撞检测
在Unity3以后版本,我们介绍了一种称为“基于层的碰撞检测”(Layer-Based Collision Detection)的东西,可以让你有选择地控制Unity对象和他们附加的特定层碰撞。
选择选定游戏对象的层.
Edit->Project Settings->Physics.,打开物理引用界面. 在碰撞矩阵中选择要与其他层相互作用的层,勾选即可.