Unity3d中参与碰撞的物体分2种类型:
一、发起碰撞的物体。
二、接收碰撞的物体。
1. 参与发起碰撞物体:Rigodbody, CharacterController 角色碰撞器。
2. 参与接收碰撞的物体:所有Collider .
工作的原理为:发生碰撞的物体中必须要有“发起碰撞”的物体。否则,碰撞不响应。
比如:两面墙都只用BoxCollider ,所以墙与墙之间无反应。
比如:一个带有Rigidbody属性的箱子,能落到带有MeshCollider属性的地面上。
比如:一个带有Rigidbody属性的箱子,可以被一个带有CharacterController 属性的人推着跑。
在所有Collider上有一个Is Trigger 的boolean型参数。
(If enabled, this Collider is used for triggering events, and is ignored by the physics engine.)
当发生碰撞反应的时候,会先检查此属性是否为true。
当激活此选项时,会调用碰撞双方的脚本 OnTrigger, 反之,脚本方面没有任何反应。
当激活is trigger = true,不会发生后续物理的反应。反之,发生后续的物理反应。
总结:Is Trigger 好比是一个物理功能的开关, 是要“物理功能”还是要“OnTrigger脚本”。
在Rigodbody 上有一个Use Gravity 的boolean型参数.
(Controls whether gravity affects this rigidbody.)
Unity 物理引擎,处理的一个细节:
当一个CharacterController不发生位置变化,一个Collier发生位置变化后,产生碰撞。将不会调用任何碰撞函数,也就是没有碰撞反应的。
物理引擎视为CharacterController无碰撞.
--------------------分隔线----------------------
现在就来考虑如何让GameObject(魔法球)主动碰撞到CC(人物), 碰撞到人物后,显示受击效果.
解决方案, 由上面的可知, 做出如下设置:
1:魔法球: Collider(合适的类型), Rigidbody(Use Gravity可以去掉)
2:人物: CC.
脚本:
在魔法球上添加脚本
void OnCollisionEnter (Collision collision) { Debug.Log ("**** collision.gameObject.name***:" + collision.gameObject.name); if(collision.gameObject.name == "Player") { // 发送攻击消息 SendAttackMsg(); // 销毁魔法球 Destroy (gameObject); } }
具体的一些,可以看 unity3d的 manual refrernce的东西,有几个表格在后面可以参考:
几个类型碰撞器:
1. 静态碰撞器: 就是只有碰撞器,但没有刚体的
2.刚体碰撞器: 带Rigidbody的碰撞器,这个是最基本的碰撞器
3.运动学刚体碰撞器: 带Rigidbody, 而且Rigidbody的IsKinematic打勾的,注意这个碰撞器是不能加力的,只能修改他的transform才能移动
Triggers 触发器
仅需要选中Inspector中的IsTrigger属性选择框。触发器不受物理引擎控制,当和一个触发器发生碰撞时会发出三个独特的触发信息,为了使两个触发器碰撞时发出碰撞事件,其中一个必须包含刚体.
今天遇到的一个情况是:如果刚体碰撞器不动,静态碰撞器去碰撞,则不会触发任何信息,而如果静态碰撞器不动,刚体碰撞器(包括运动学刚体碰撞器)去碰撞静态碰撞器,则会触发碰撞,如果是触发器,则会触发事件。所以下面的表格提供了触发的条件,但主动性大家也还需要注意,不然要纠结一段时间的。
Static Collider |
Rigidbody Collider |
Kinematic |
Static |
Rigidbody |
Kinematic Rigidbody |
|
Static Collider 静态碰撞器 |
Y |
|||||
Rigidbody Collider 刚体碰撞器 |
Y |
Y |
Y |
|||
Kinematic Rigidbody Collider |
Y |
|||||
Static Trigger Collider |
||||||
Rigidbody Trigger Collider |
||||||
Kinematic Rigidbody Trigger Collider |
Static Collider |
Rigidbody Collider |
Kinematic |
Static |
Rigidbody |
Kinematic Rigidbody |
|
Static Collider 静态碰撞器 |
Y |
Y |
||||
Rigidbody Collider 刚体碰撞器 |
Y |
Y |
Y |
|||
Kinematic Rigidbody Collider |
Y |
Y |
Y |
|||
Static Trigger Collider 静态触发碰撞器 |
Y |
Y |
Y |
Y |
||
Rigidbody Trigger Collider |
Y |
Y |
Y |
Y |
Y |
Y |
Kinematic Rigidbody Trigger Collider |
Y |
Y |
Y |
Y |
Y |
Y |
下面就是我做的测试情况,都是A物体去撞B物体。
一、A(碰撞体),B(没有碰撞体,无论有没有刚体),没有触发事件。
二、A(碰撞体),B(碰撞体),没有触发事件。
二、A(碰撞体和刚体,开启IsTrigger),B(碰撞体,关闭IsTrigger),双方都能收到触发事件。
三、A(碰撞体和刚体,关闭IsTrigger),B(碰撞体,开启IsTrigger),双方都能收到触发事件。
四、A (碰撞体,关闭IsTrigger),B(碰撞体和刚体,开启IsTrigger),没有触发事件。
五、A (碰撞体,开启IsTrigger),B(碰撞体和刚体,关闭IsTrigger),没有触发事件。
额外实验:
六、A(碰撞体和刚体,开启IsTrigger)自由下落,B(碰撞体)撞击A,双方都能收到触发事件。
根据上面的实验得出,如果要收到触发事件,必须满足如下三个条件:
1、必须都要有碰撞器组件(Collider),其实上面的碰撞事件同样也需要这个前提条件。
2、必须有一个物体带刚体组件,并且处于运动状体中(包括主动运动去撞击别人和在运动过程中被别人撞击)。
3、两个碰撞器中至少有一个开启了IsTrigger。
此外还有两点:
一、产生触发事件的两个物体会相互穿越,准确的说是因为开启IsTrigger那个物体会被物理引擎锁忽略掉,所以会产生两个物体穿越的情况。
二、两个对象要么都收到碰撞事件,要么都收到触发事件,不会出现一个收到触发事件,一个收到碰撞事件的情况。
还有一个经验点就是,在控制一个物体A去撞另一个物体B时,不要直接去修改物体A的Transform的position属性,因为你会发现如果即使两者发生了碰撞也还是会穿越的,原因就在于我们是直接设置的坐标,如果物体A有刚体组件的话,应该用AddForce,给物体添加一个力,然后让物理引擎去让物体动,此时如果发生了碰撞的话,就不会穿越了。
好吧,下午折腾了半天之后,我就一直在想那个IsTrigger有啥用,后来在网上搜了一下,说是可以做门的自动打开,就让我想起了Unity3d 4自带的哪个AngryBots例子,貌似当控制主角走到一个门前时,那个门会自动打开。