碰撞器检测和触发器检测

无论是碰撞检测还是触发检测,他们都基于Collider组件。两个游戏对象发生碰撞时,碰撞器可以产生系统默认的碰撞产生的物理效果;触发器可以让用户自定义碰撞后产生的物理效果,如爆炸、消失等。
在Unity中,用来检测碰撞的方法有三种:碰撞检测、触发检测、射线检测。在这里我们只讲解碰撞检测和触发检测。

一、碰撞检测

首先在Unity里面,碰撞器是一种组件,有很多种类,大致分为两类:基本碰撞器和非基本碰撞器;其中基本碰撞器包括Box Collider(Cube游戏物体自带的碰撞器)、Sphere Collider(Sphere自带的碰撞器)、Capsule Collider(Capsule自带)等,而非基本碰撞器包括Wheel Collider(车轮碰撞器)、Mesh Collider(网格碰撞器,Plane自带)等。

基本碰撞器的属性基本都一样,只是因为形状不一样而有数值上的差异,而非基本碰撞器比较特殊,每一个都可以拿出来单独介绍。这里我们详细讲解一下基本碰撞器,而非基本碰撞器我们后续章节再做详细介绍。
如图1.1和1.2分别是Cube和Sphere自带的碰撞器:

图1.1
图1.2

对比两张图片我们可以看出它们都拥有Edit Collider、Is Trigger、Material、Center属性,因为形状的不同才会有了Size和Radius的差别。

1、Edit Collider

单击选中一个游戏对象的Edit Collider选项后,游戏对象身上会出现包裹全身的网格,上面还有光点,如图1.3:

图1.3

点击鼠标左键拖动光点,就可以改变Size或者Radius等的大小,也就是改变了碰撞器的大小。

2、Is Trigger

这个属性就是碰撞器和触发器的区别,勾选这个属性就是触发器,不勾选就是碰撞器。这里我们先不勾选。

3、Material-材质

默认是None,可以添加其它物理材质(Physic Material),用来设置弹性系数和摩擦系数,上一章有介绍。

4、Center

用来调整Collider的位置,如图1.4:

图1.4

由图可以看出Collider的位置和游戏对象位置并不冲突,两方都是独立的,一个游戏对象的默认碰撞器的位置和游戏对象本身的位置一致。

5、Unity中碰撞器有三个自带的方法,当游戏对象发生碰撞时调用,他们分别是OnCollisionEnter、OnCollisionStay、OnCollisionExit,这就是所谓的碰撞检测方法。

OnCollisionEnter:两个碰撞游戏对象的碰撞器刚接触时(注意,不是游戏对象接触,是游戏对象上的碰撞器-Collider组件接触)调用一次。
OnCollisionStay:两个游戏对象的碰撞器接触时调用,只要两个碰撞器一直在接触,就会一直调用该方法。
OnCollisionExit:两个游戏对象的碰撞器相互分离时调用一次。

下面用几个情形来说明一下什么条件(两个游戏对象是否带有刚体和碰撞器)下会调用上述三种碰撞检测方法。
情形一:两个游戏对象都具有刚体和碰撞器时

我们先给两个游戏对象(Cube和Sphere)分别添加刚体,这两个游戏对象都自带有碰撞器-Collider,这里我们不要改变Collider的Center的值,让Collider和物体位置一致;然后我们给两个物体都添加一个脚本,脚本的内容就是利用上述三种方法在控制台打印出相应的调用方法的名字。
小球的脚本代码:
<code>
private Rigidbody rb;
// Use this for initialization
void Start () {
rb=GetComponent<Rigidbody>();
}

// Update is called once per frame
void Update () {
    if (Input.GetMouseButtonDown(0))
    {
       // this.transform.Translate(new Vector3(1,0,0));//小球没有刚体时让其移动的方法
        rb.AddForce(new Vector3(1, 0, 0));//小球拥有刚体时让其移动的方法
        //两种方法根据情形不同选择其中一个
    }
}
void OnCollisionEnter()
{
    print("小球调用了OnCollisionEnter方法");
}
void OnCollisionStay()
{
    print("小球调用了OnCollisionStay方法");
}
void OnCollisionExit()
{
    print("小球调用了OnCollisionExit方法");
}

</code>
方块的脚本代码:
<code>
// Use this for initialization
void Start () {

}

// Update is called once per frame
void Update () {

}
void OnCollisionEnter()
{
    print("方块调用了OnCollisionEnter方法");
}
void OnCollisionStay()
{
    print("方块调用了OnCollisionStay方法");
}
void OnCollisionExit()
{
    print("方块调用了OnCollisionExit方法");
}

</code>
把写好的脚本分别加入相应的游戏对象中,然后我们就单击运行按钮,查看Console视图的打印内容,如图情形一:


情形一.1

图情形一.1可以看出小球和方块都调用了OnCollisionEnter和OnCollisionStay方法,其中OnCollisionEnter都只调用了一次(Plane自带的有Mesh Collider),OnCollisionStay方法一直在调用;至于方法调用的先后顺序是:OnCollisionEnter>OnCollisionStay>OnCollisionExit,而之所以先调用了方块的方法是因为方块先落的地。

情形一.2

有上面两个图我们可以得出:当两个游戏对象都拥有刚体和碰撞器时,他们在碰撞时都会打印碰撞器的三种方法。

情形二:小球有刚体和碰撞器,方块只有碰撞器时

如图情形二:

情形二.1
情形二.2

得出:当两个游戏对象一方拥有刚体和碰撞器,另一方只拥有碰撞器时,只要两方发生碰撞,就会调用碰撞方法。

情形三:小球和方块都只有碰撞器,没有刚体

此时小球没有了刚体,我们让它移动要利用另外一种方法,上面代码有写,这里直接用就行了。
如图情形三:

情形三

得出:当两个游戏对象只拥有碰撞器,它们互相碰撞接触时不会调用碰撞方法。

情形四:一方(小球)带有刚体和碰撞器,另一方(方块)只带有刚体,没有碰撞器。

如图情形四:
首先我们要把方块的碰撞器组件-Box Collider取消勾选,如图情形四.1:

情形四.1
情形四.2

为了验证小球和方块的碰撞,我们把小球放到了方块的正下方,这样方块落下时就会和小球碰撞接触了,如图情形四.3。


情形四.3
情形四.4

得出:当一方有刚体和碰撞器,另一方只有刚体,两方相互碰撞接触时,都不会调用碰撞方法。

由此得出结论:

两个物体碰撞调用碰撞方法的前提是必须两个物体都拥有碰撞器—Collider,而且其中一方必须带有刚体组件。

二、触发检测

触发检测就要用到触发器,而触发器可以说就是一种特殊的碰撞器,因为只要把碰撞器组件中的Is Trigger属性勾选上,就变成了触发器。
和碰撞检测类似,触发检测也有三种方法,分别是OnTriggerEnter、OnTriggerStay、OnTriggerExit。
触发检测的验证也有很多情形,根据两个游戏对象的条件(是否带有刚体和触发器)的不同大致分为:双方都带有刚体和触发器、一方带有刚体和触发器,另一方只有刚体、一方带有刚体和触发器,另一方只有触发器、双方都只有刚体、双方都只有触发器。
这里就介绍一个情形下(一方带有刚体和触发器,另一方只有刚体)的触发检测方法的调用情况,其它情形自行操作。
当选中Is Trigger后,碰撞器就变成了触发器,如果此时我们再给游戏对象添加一个刚体,那么游戏对象就会一直坠落,因为没有了碰撞器,所以我们要想让游戏对象有刚体而又不坠落,我们就要选中刚体组件中的Is Kinematic属性,如图1.5:

图1.5

选中后,我们让小球带有刚体和触发器,让方块只带有刚体。此时改一下小球和方块的代码,把触发检测的三个方法写进去,然后我们运行项目,操作小球移动,观察打印结果,如图1.6:

图1.6
后面几种情形自行实验过后我们就得出了一个结论:

只要有一方游戏对象带有刚体和触发器,另一方不管是否带有刚体和触发器,两个游戏对象都会调用触发检测方法。

三、碰撞检测和触发检测的异同
相同点:

1、两种检测的基础都是Collider组件;
2、两种检测的三种方法类似;

不同点:

1、碰撞检测必须两个Collider组件都不勾选Is Trigger,只要勾选了,就会进入触发检测;
2、触发检测和碰撞检测有冲突,不能同时存在,只能存在一个;

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,332评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,508评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,812评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,607评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,728评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,919评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,071评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,802评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,256评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,576评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,712评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,389评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,032评论 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,798评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,026评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,473评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,606评论 2 350

推荐阅读更多精彩内容