要产生碰撞必须为游戏对象添加刚体(Rigidbody)和(各种类型的3D/2D)碰撞器(Collider),刚体可以让物体在物理影响下运动.下面先讲3D情况下:
两个物体都必须带有碰撞器(Collider),运动的物体还必须带有Rigidbody刚体。
在unity3d中,能检测碰撞发生的方式有两种,一种是利用碰撞器,另一种则是利用触发器.
碰撞器:一群组件,它包含了很多种类,比如:Box Collider(盒碰撞体),Mesh Collider(网格碰撞体)等,这些碰撞器应用的场合不同,但都必须加到GameObjecet身上。
触发器,只需要在检视面板中的碰撞器组件中勾选IsTrigger属性选择框。
触发信息检测:当Is Trigger=true时,碰撞器被物理引擎所忽略,没有碰撞效果,可以调用OnTriggerEnter/Stay/Exit函数。
1.MonoBehaviour.OnTriggerEnter(Collider collider)当进入触发器
2.MonoBehaviour.OnTriggerExit(Collider collider)当退出触发器
3.MonoBehaviour.OnTriggerStay(Collider collider)当逗留触发器
碰撞信息检测:当Is Trigger=false时,碰撞器根据物理引擎引发碰撞,产生碰撞的效果,可以调用OnCollisionEnter/Stay/Exit函数;
1.MonoBehaviour.OnCollisionEnter(Collision collision) 当进入碰撞器
2.MonoBehaviour.OnCollisionExit(Collision collision) 当退出碰撞器
3.MonoBehaviour.OnCollisionStay(Collision collision) 当逗留碰撞器
collider的性能和效率大概的顺序是:Sphere Collider > Capsule > Box Collider > Mesh Collider
碰撞器是另一种组件,它和刚体一起,来使碰撞发生。如果两个刚体撞在一起,物理引擎将不会计算碰撞除非它们包含一个碰撞器组件。没有碰撞器的刚体,会在物理模拟中相互穿透。碰撞器必须独立于刚体加在对象上。碰撞器并不一定需要附加刚体,但是要使移动物体具有碰撞效果必须附加刚体。为了使两个触发器碰撞时发出碰撞事件,其中一个必须包含刚体。
网格碰撞器之间通常不相互碰撞,但如果一个网格碰撞器被标记为凸起的(Convex ),那么它就可以与其他网格碰撞器碰撞,对移动的对象使用基本/组合碰撞器,而对静态环境对象使用网格碰撞器。碰撞网格使用背面剔除(或译背面拣选,指正面多边形挡住了在它后面的背面多边形,Direct3D将通过拣选(即删除多余的处理过程)背面多边形来提高效率的过程。)如果一个对象和被背面剔除的网格碰撞,那也不会在物理上碰撞。
Unity组件文中将碰撞体分为3个类型:
1:Static Collider 静态碰撞器
指的是没有附加刚体而附加了碰撞器的游戏对象。这类对象会保持静止或者很轻微的移动。对于环境模型十分好用,当和刚体碰撞时而不会移动。
2:Rigidbody Collider 刚体碰撞器
指的是同时附加了刚体和碰撞器的游戏对象。通过脚本的力量和碰撞完全受物理引擎的影响。可以和只包含碰撞器的游戏对象碰撞。将会成为你游戏中使用物理效果的基本类型碰撞器。
3:Kinematic Rigidbody Collider 运动学刚体碰撞器
指的是同时包含碰撞器和刚体,并且激活IsKinematic的一类游戏对象,要移动这类游戏对象,要修改它的Transform组件(指的是position和rotation这类属性),而不是用力。它们很像静态碰撞器,不过如果你想要不停地到处移动碰撞器,它们会更好用。这类游戏对象还有许多其他的独特使用情景。
运动学刚体碰撞器是个非常懒惰和霸道的家伙,它碰到其他碰撞器完全没有反应(其实还是有点反应,会触发一些碰撞函数的,后面有解释)。它不受力、重力或扭矩的影响。可以通过设置Transform 的position和rotation来准确的操作它们或者让它们动起来,但是,它们可以和其他的非运动学刚体互相作用。对于放在运动学刚体碰撞器上面的刚体,会受到运动学刚体施加的摩擦力。
4:Character Controllers 角色控制器
如果想制作一个类似人的角色那就使用角色控制器。这可以是第三人称平台游戏、第一人称射击游戏的主要角色或任何敌对角色。
这类控制器不遵循物理规则因此它感觉上不对劲(在Doom中,你跑到了90英里每小时,然后马上停下而且可以极快的转身)。不过,角色控制器执行碰撞检测以保证你的角色可以沿着墙滑动,上下台阶等等。
角色控制器不受力影响(但是重力效果还是有的)但是可以被由代码施加的力推动。通常,所有类似人的角色都用角色控制器来执行。
角色控制器本身不具物理特性,因此如果想应用真正的物理作用——在绳上摇摆,被大石头推动——到你的角色,必须用刚体,这会允许你把铰链或力用到你的角色上。角色控制器永远沿Y轴对齐,因此,如果你的角色需要在空间中改变方向那也必须用到刚体(比如在变化的引力控制下)。但是,要意识到调整一个刚体在角色上表现自然是很难的,因为游戏角色自身的非物理特性总想表现出来。另一个困难是,角色控制器可以从特定高度的台阶上平滑地滑下,而刚体不会。
控制器不会对加在它自身上的力做出反应,也不会自动推开其他刚体。(这里我没有明白,因为我实验过在一个刚体内部实例化一个控制器,刚体是会被弹开的。如果有人懂请告诉我,不胜感激!)
如果想让角色控制器推开其他刚体或者对象,你可以在对象附加的脚本中添加OnControllerColliderHit()函数,这样对它们施加力就能够产生碰撞。
也就是说,角色控制器可以使用物理效果影响其他对象,前提是你自己写了脚本。
而角色控制器不能通过物理效果被其他对象影响。因此,如果你想让你的游戏角色被物理效果影响,那就最好使用刚体而不是角色控制器。
角色控制器和运动学刚体有点像,因为它们都不受力的作用(运动学刚体更像是一个刚体,只是不会受到其他任何外力的影响,就像是古代的国王,虽然和普通平民一样都是人,但是只能他欺负别人,别人无法欺负他;而角色控制器本身就不具有物理特性,不可以推开别人(除非写了自己的脚本),也不会被别人影响,只是它可以执行碰撞检测)。但是也有几点不同的地方。首先,运动学刚体是无法通过代码施加力的作用来推动,但是角色控制器是可以的。第二,运动学刚体不会受到重力的作用,而角色控制器是有重力效果的。其次,角色控制器只能沿Y轴旋转,也就是人永远都是直立状态,不会因为受到力的作用就趴下啦,而刚体是可以的。第三,角色控制器可以从特定高度台阶上平滑地滑下,而刚体不会。
刚体休眠:静止的刚体会进入休眠。例如,当一个正方体掉到地板上静止后就会进入刚体休眠.刚体休眠完全自动发生,只要刚体的速度低于sleepAngularVelocity和sleepVelocity,该刚体就会开始休眠.其空闲一些帧后,就会被设置成休眠状态,处于休眠状态中的物体,不会再对其进行碰撞检测和模拟。这会节约大量的CPU开销。移动的静态碰撞器无法唤醒它.运动学刚体由于会对刚体产生力的作用而可以唤醒休眠中的刚体.
实例:都是A物体去撞B物体
一、A(碰撞体),B(没有碰撞体,无论有没有刚体),没有触发事件。
二、A(碰撞体),B(碰撞体),没有触发事件。
二、A(碰撞体和刚体,开启IsTrigger),B(碰撞体,关闭IsTrigger),双方都能收到触发事件。
三、A(碰撞体和刚体,关闭IsTrigger),B(碰撞体,开启IsTrigger),双方都能收到触发事件。
四、A (碰撞体,关闭IsTrigger),B(碰撞体和刚体,开启IsTrigger),没有触发事件。
五、A (碰撞体,开启IsTrigger),B(碰撞体和刚体,关闭IsTrigger),没有触发事件。
只要A有带有碰撞体和刚体,正在运动,B带有碰撞体,不管是A撞B还是B撞A,A和B至少一个开启了IsTrigger,都会触发事件.
结论:产生触发事件的两个物体会相互穿越,准确的说是因为开启IsTrigger那个物体会被物理引擎锁忽略掉,所以会产生两个物体穿越的情况。两个对象要么都收到碰撞事件,要么都收到触发事件,不会出现一个收到触发事件,一个收到碰撞事件的情况。要使用AddForce/AddTorque利用物理引擎去操作,如果直接设置坐标,2个物体产生碰撞,但是会穿越彼此.
关于各种Collider的效率高低排序为
sphere Collider> capsule collider> box Collider> mesh Collider
参考:http://www.ceeger.com/Manual/Physics.html
https://docs.unity3d.com/Manual/PhysicsSection.html
http://www.cnblogs.com/slysky/p/4290803.html
pc:Physics.Raycast()方法中,源头一般是摄像机,方向一般是从屏幕方向射向内部3D空间,用屏幕坐标转向视口坐标Camera.main.ScreenToViewportPoint表示方向,RaycastHit hit信息,设置LayerMask.