一,基本碰撞和触发器的基本概念
1>什么是碰撞器
碰撞器是一群组件,它包含了很多种类,比如: Box Collider 盒碰撞器、Capsule Collider 胶囊碰撞器、Mesh Collider 网格碰撞器、Sphere Collider 球碰撞器 等等这一类组件,这些碰撞器应用的场合不同,但都必须加到GameObjecet身上。
2>什么是触发器
所谓触发器,只需要在检视面板中的碰撞器组件中勾选IsTrigger属性选择框。
3>区别:
碰撞器
(1)碰撞器有碰撞效果
(2)IsTrigger=false
(3)碰撞信息检测
MonoBehaviour.OnCollisionEnter(Collision collision)
MonoBehaviour.OnCollisionExit(Collision collision)
MonoBehaviour.OnCollisionStay(Collision collision)
触发器
(1)触发器没有碰撞效果
(2)IsTrigger=true;
(3)触发信息检测:
MonoBehaviour.OnTriggerEnter(Collider collider)
MonoBehaviour.OnTriggerExit(Collider collider)
MonoBehaviour.OnTriggerStay(Collider collider)
二,触发和碰撞的信息检测方法
1>触发信息检测:
1.MonoBehaviour.OnTriggerEnter( Collider other )当进入触发器
2.MonoBehaviour.OnTriggerExit( Collider other )当退出触发器
3.MonoBehaviour.OnTriggerStay( Collider other )当逗留触发器
2>碰撞信息检测:
1.MonoBehaviour.OnCollisionEnter( Collision collisionInfo ) 当进入碰撞器
2.MonoBehaviour.OnCollisionExit( Collision collisionInfo ) 当退出碰撞器
3.MonoBehaviour.OnCollisionStay( Collision collisionInfo ) 当逗留碰撞器
以上这六个接口都是MonoBehaviour的函数,由于我们新建的脚本都继承这个MonoBehaviour这个类。所以我们的脚本里面可以覆写这六个函数。
我们就需要完善的了解一下有关碰撞器方面的知识啊。我把我们还得了解的概念列举如下:
1.Static Collider 静态碰撞器
指的是没有附加刚体而附加了碰撞器的游戏对象。这类对象会保持静止或很轻微的移动。这对于环境模型十分好用,比如刚体和墙面碰撞时而不会移动。
2.Rigidbody Collider 刚体碰撞器
指的是附加了刚体和碰撞器的游戏对象。
3.Kinematic Rigidbody Collider 运动学刚体碰撞器
在第2点得基础上勾选了刚体组件中的IsKinematic属性,如果要移动这类对象,就只能修改它的Transform,而不是用力。这类游戏对象还有许多其他的独特的使用情景。
这三种碰撞器如果勾选了IsTrigger复选框,就变成了相应的触发器了。
三,碰撞和触发的必要条件
1>碰撞测试
需要碰撞体(Collider),那么是不是只要有Collider就可以发生碰撞了呢?
图为红色cube碰撞蓝色cube后自己被弹飞了,而蓝色cube却毫发无伤;
如果是蓝色碰红色则还是会发生穿越;
同理,如果是蓝色加了刚体而红色未加,那么和上面的情况则是相反的。
现在我们把两个cube都加上刚体
两个cube都被弹开了,即都发生了碰撞。
为了更加直观的看出结果,下面列一个表格:
2>碰撞结论:
1、如果两个物体,只要有一个没有Collider,即使任意一个物体有rigidbody,都会发生穿越(即,没Collider就穿越);
2、如果两个物体都有Collider,有rigidbody的物体会发生碰撞,而没有rigidbody的一方则不会受到影响(注意一下谁碰谁);
3、如果两个物体都有Collider,无rigidbody的物体碰有rigidbody的物体,则并不会发生碰撞
(易忽略,单独拿出来讲。另外这种情况下,当高速移动无rigidbody的物体时,偶尔会出现发生碰撞的现象,不知道是不是unity的一个bug)
综上,两物体发生碰撞的必要条件是:
两个物体都必须带有碰撞器(Collider),其中至少一个物体带有Rigidbody刚体。(只有带Rigidbody刚体的一方会受到物理引擎的影响)
可能会有人想如果为物体都加上刚体不就不需要这么纠结了吗?
有两方面原因:
一是游戏场景物体很多,都加刚体,系统的开销会很大;
二是有时候我就需要其中一个物体是不动的,比如地面。
注意:
1 、 在一次碰撞中,“刚接触”和“接触完”只被调用一次,而“碰撞中”则是在接触时一直被调用。
2 、函数的参数则是被撞的那个物体 。我们可以通过此参数获取被撞物体信息。
3>触发测试
碰撞信息检测的例子不变,我们只把蓝色cube的IsTrigger勾上
再运行试试,这时,发现原来的碰撞信息不见了,并且红色cube穿过了蓝色cube
此时在蓝色cube上加上以下代码:
可见IsTrigger的作用是忽略物理引擎的影响,没有碰撞效果(OnCollisionEnter/Stay/Exit函数也就会失效了),并可以调用OnTriggerEnter/Stay/Exit函数。
注意:OnTriggerEnter(Collider collider)和OnCollisionEnter(Collision collision)不能同时使用。
和碰撞实验一样,我们也来做一个表格看看刚体和触发器的关系
和上面的例子代码不同,我们稍微修改一下代码:
红色cube上的脚本:
蓝色cube上的脚本:
4>触发结论
(由于碰撞器是触发器的载体,而触发器只是碰撞器身上的一个属性,要触发必然需要碰撞器,所以表中并没有Collider这一项)
其实到这里我们已经可以得出结论了,下面的情况就不一一列举了
结论:
1、和碰撞不同,触发无论谁碰谁,结果都一样;
2、触发的必要条件:至少有一个碰撞器勾选了IsTrigger,至少有一个物体具有刚体,才会触发;
3 、 碰撞和触发的联系和区别以及何时使用它们
通过以上实验,相信对于碰撞和触发的区别有了一个大致的了解了。
那么什么时候用碰撞,什么时候用触发呢?
由于碰撞是可以发生物理效果的同时触发事件,而触发是不发生物理效果的情况下触发事件;
所以,还是具体情况具体对待,知道了原理就灵活运用吧。
举个例子来说吧。
足球射到墙上会发生碰撞,而足球出界了并不会发生碰撞,而是裁判吹哨这个事件被触发。
那么你就可以在墙上加一个碰撞体不勾选IsTrigger,而出界线加一个Collider并勾上IsTrigger。
四,碰撞和检测的相关的注意点
两个注意
注意1:
两个物体发生碰撞,如果要检测到碰撞信息,那么其中必有一个物体既带有碰撞器,又带有刚体,且检测碰撞信息的脚本必须附着在带有刚体的碰撞器上。
1>什么是碰撞器
碰撞器是一群组件,它包含了很多种类,比如: Box Collider 盒碰撞器、Capsule Collider 胶囊碰撞器、Mesh Collider 网格碰撞器、Sphere Collider 球碰撞器 等等这一类组件,这些碰撞器应用的场合不同,但都必须加到GameObjecet身上。
2>什么是触发器
所谓触发器,只需要在检视面板中的碰撞器组件中勾选IsTrigger属性选择框。
3>区别:
碰撞器
(1)碰撞器有碰撞效果
(2)IsTrigger=false
(3)碰撞信息检测
MonoBehaviour.OnCollisionEnter(Collision collision)
MonoBehaviour.OnCollisionExit(Collision collision)
MonoBehaviour.OnCollisionStay(Collision collision)
触发器
(1)触发器没有碰撞效果
(2)IsTrigger=true;
(3)触发信息检测:
MonoBehaviour.OnTriggerEnter(Collider collider)
MonoBehaviour.OnTriggerExit(Collider collider)
MonoBehaviour.OnTriggerStay(Collider collider)
二,触发和碰撞的信息检测方法
1>触发信息检测:
1.MonoBehaviour.OnTriggerEnter( Collider other )当进入触发器
2.MonoBehaviour.OnTriggerExit( Collider other )当退出触发器
3.MonoBehaviour.OnTriggerStay( Collider other )当逗留触发器
2>碰撞信息检测:
1.MonoBehaviour.OnCollisionEnter( Collision collisionInfo ) 当进入碰撞器
2.MonoBehaviour.OnCollisionExit( Collision collisionInfo ) 当退出碰撞器
3.MonoBehaviour.OnCollisionStay( Collision collisionInfo ) 当逗留碰撞器
以上这六个接口都是MonoBehaviour的函数,由于我们新建的脚本都继承这个MonoBehaviour这个类。所以我们的脚本里面可以覆写这六个函数。
我们就需要完善的了解一下有关碰撞器方面的知识啊。我把我们还得了解的概念列举如下:
1.Static Collider 静态碰撞器
指的是没有附加刚体而附加了碰撞器的游戏对象。这类对象会保持静止或很轻微的移动。这对于环境模型十分好用,比如刚体和墙面碰撞时而不会移动。
2.Rigidbody Collider 刚体碰撞器
指的是附加了刚体和碰撞器的游戏对象。
3.Kinematic Rigidbody Collider 运动学刚体碰撞器
在第2点得基础上勾选了刚体组件中的IsKinematic属性,如果要移动这类对象,就只能修改它的Transform,而不是用力。这类游戏对象还有许多其他的独特的使用情景。
这三种碰撞器如果勾选了IsTrigger复选框,就变成了相应的触发器了。
三,碰撞和触发的必要条件
1>碰撞测试
需要碰撞体(Collider),那么是不是只要有Collider就可以发生碰撞了呢?
图为两个只加了Collider的cube,运行后两个cube发生了穿越;
此时我们为红色的cube加一个刚体图为红色cube碰撞蓝色cube后自己被弹飞了,而蓝色cube却毫发无伤;
如果是蓝色碰红色则还是会发生穿越;
同理,如果是蓝色加了刚体而红色未加,那么和上面的情况则是相反的。
现在我们把两个cube都加上刚体
两个cube都被弹开了,即都发生了碰撞。
为了更加直观的看出结果,下面列一个表格:
2>碰撞结论:
1、如果两个物体,只要有一个没有Collider,即使任意一个物体有rigidbody,都会发生穿越(即,没Collider就穿越);
2、如果两个物体都有Collider,有rigidbody的物体会发生碰撞,而没有rigidbody的一方则不会受到影响(注意一下谁碰谁);
3、如果两个物体都有Collider,无rigidbody的物体碰有rigidbody的物体,则并不会发生碰撞
(易忽略,单独拿出来讲。另外这种情况下,当高速移动无rigidbody的物体时,偶尔会出现发生碰撞的现象,不知道是不是unity的一个bug)
综上,两物体发生碰撞的必要条件是:
两个物体都必须带有碰撞器(Collider),其中至少一个物体带有Rigidbody刚体。(只有带Rigidbody刚体的一方会受到物理引擎的影响)
可能会有人想如果为物体都加上刚体不就不需要这么纠结了吗?
有两方面原因:
一是游戏场景物体很多,都加刚体,系统的开销会很大;
二是有时候我就需要其中一个物体是不动的,比如地面。
注意:
1 、 在一次碰撞中,“刚接触”和“接触完”只被调用一次,而“碰撞中”则是在接触时一直被调用。
2 、函数的参数则是被撞的那个物体 。我们可以通过此参数获取被撞物体信息。
3>触发测试
碰撞信息检测的例子不变,我们只把蓝色cube的IsTrigger勾上
再运行试试,这时,发现原来的碰撞信息不见了,并且红色cube穿过了蓝色cube
此时在蓝色cube上加上以下代码:
注意:OnTriggerEnter(Collider collider)和OnCollisionEnter(Collision collision)不能同时使用。
和碰撞实验一样,我们也来做一个表格看看刚体和触发器的关系
和上面的例子代码不同,我们稍微修改一下代码:
红色cube上的脚本:
蓝色cube上的脚本:
4>触发结论
(由于碰撞器是触发器的载体,而触发器只是碰撞器身上的一个属性,要触发必然需要碰撞器,所以表中并没有Collider这一项)
其实到这里我们已经可以得出结论了,下面的情况就不一一列举了
结论:
1、和碰撞不同,触发无论谁碰谁,结果都一样;
2、触发的必要条件:至少有一个碰撞器勾选了IsTrigger,至少有一个物体具有刚体,才会触发;
3 、 碰撞和触发的联系和区别以及何时使用它们
通过以上实验,相信对于碰撞和触发的区别有了一个大致的了解了。
那么什么时候用碰撞,什么时候用触发呢?
由于碰撞是可以发生物理效果的同时触发事件,而触发是不发生物理效果的情况下触发事件;
所以,还是具体情况具体对待,知道了原理就灵活运用吧。
举个例子来说吧。
足球射到墙上会发生碰撞,而足球出界了并不会发生碰撞,而是裁判吹哨这个事件被触发。
那么你就可以在墙上加一个碰撞体不勾选IsTrigger,而出界线加一个Collider并勾上IsTrigger。
四,碰撞和检测的相关的注意点
两个注意
注意1:
两个物体发生碰撞,如果要检测到碰撞信息,那么其中必有一个物体既带有碰撞器,又带有刚体,且检测碰撞信息的脚本必须附着在带有刚体的碰撞器上。
注意2:
两个GameObject发生碰撞,要想检测到触发信息,最少要有一个刚体碰撞器并且勾选了IsTrigger复选框,另一个最少要有一个碰撞器组件,此时检测碰撞的脚本必须附加在那个带有刚体的触发器上。