Unity3D中的碰撞检测.docx

上传人:b****8 文档编号:9620498 上传时间:2023-02-05 格式:DOCX 页数:9 大小:88.97KB
下载 相关 举报
Unity3D中的碰撞检测.docx_第1页
第1页 / 共9页
Unity3D中的碰撞检测.docx_第2页
第2页 / 共9页
Unity3D中的碰撞检测.docx_第3页
第3页 / 共9页
Unity3D中的碰撞检测.docx_第4页
第4页 / 共9页
Unity3D中的碰撞检测.docx_第5页
第5页 / 共9页
点击查看更多>>
下载资源
资源描述

Unity3D中的碰撞检测.docx

《Unity3D中的碰撞检测.docx》由会员分享,可在线阅读,更多相关《Unity3D中的碰撞检测.docx(9页珍藏版)》请在冰豆网上搜索。

Unity3D中的碰撞检测.docx

Unity3D中的碰撞检测

很多时候,当我们的主角与其他GameObject发生碰撞时,我们需要做一些特殊的事情,比如:

子弹击中敌人,敌人就得执行一系列的动作。

这时,我们就需要检测到碰撞现象,即碰撞检测。

这一篇,我来具体谈谈自己所了解的碰撞检测,希望高手不佞赐教。

  首先,我们得明确一点:

即产生碰撞信息所需要的条件。

事实上,在unity3d中,能检测碰撞发生的方式有两种,一种是利用碰撞器,另一种则是利用触发器。

这两种方式的应用非常广泛。

为了完整的了解这两种方式,我们必须理解以下概念:

  

(一)碰撞器是一群组件,它包含了很多种类,比如:

BoxCollider,CapsuleCollider等,这些碰撞器应用的场合不同,但都必须加到GameObjecet身上。

  

(二)所谓触发器,只需要在检视面板中的碰撞器组件中勾选IsTrigger属性选择框。

  (三)在Unity3d中,主要有以下接口函数来处理这两种碰撞检测:

触发信息检测:

1.MonoBehaviour.OnTriggerEnter(Colliderother)当进入触发器

2.MonoBehaviour.OnTriggerExit(Colliderother)当退出触发器

3.MonoBehaviour.OnTriggerStay(Colliderother)当逗留触发器

碰撞信息检测:

1.MonoBehaviour.OnCollisionEnter(CollisioncollisionInfo)当进入碰撞器

2.MonoBehaviour.OnCollisionExit(CollisioncollisionInfo)当退出碰撞器

3.MonoBehaviour.OnCollisionStay(CollisioncollisionInfo)  当逗留碰撞器

以上这六个接口都是MonoBehaviour的函数,由于我们新建的脚本都继承这个MonoBehaviour这个类。

所以我们的脚本里面可以覆写这六个函数。

下面让我举一个例子来详细讲解这几个函数的作用:

    首先,我们在这个工程中新建一个场景,取名为:

TestCollision。

然后在Project面板中新建两个文件夹,分别取名为Materials和CustomScripts。

接着,我们在Materials中新建三个材质球:

Cube1,Cube2,Plane,并分别给他们三种不同的颜色。

在CustomScripts文件夹下新建一个C#脚本,取名为:

TestCollider。

接下来,我们在场景中建立三个GameObject:

Cube1,Cube2,Plane,如下图:

其中右边绿色的正方体是Cube1,左边蓝色的是Cube2,黄灰色底板是Plane。

至此,我们最初的测试场景就搭建好了,下面,我们来编写脚本来验证我们的推断了。

首先,我们验证一下碰撞检测。

TestCollider代码如下:

usingUnityEngine;

usingSystem.Collections;

publicclassTestCollider:

MonoBehaviour{

  publicTransformcube;//将要碰撞到的GameObject的transform

  publicfloatspeed=1.0f;

  publicVector3dir=Vector3.zero;

  voidStart(){

      if(cube){

        dir=cube.position-transform.position;

        dir=dir.normalized;

      }

     

  }

  voidUpdate(){

      transform.Translate(dir*Time.deltaTime*speed);

  }

  voidOnCollisionEnter(CollisioncollisionInfo)

  {

      Debug.Log("碰撞到的物体的名字是:

"+collisionInfo.gameObject.name);

  }

}

将Cube2从Hierarchy面板上拖拽到脚本中的Cube选项中。

这段代码并不难理解,就是Cube1一直向右移动时与Cube2发生碰撞产生碰撞信息,打印碰撞到的物体的名字。

  可现实总是那么的残酷,这个碰撞信息就一直没打印出来。

哎,到底问题出在哪呢?

这时,我们就需要完善的了解一下有关碰撞器方面的知识啊。

我把我们还得了解的概念列举如下:

1.StaticCollider静态碰撞器

指的是没有附加刚体而附加了碰撞器的游戏对象。

这类对象会保持静止或很轻微的移动。

这对于环境模型十分好用,比如刚体和墙面碰撞时而不会移动。

2.RigidbodyCollider刚体碰撞器

指的是附加了刚体和碰撞器的游戏对象。

3.KinematicRigidbodyCollider运动学刚体碰撞器

在第2点得基础上勾选了刚体组件中的IsKinematic属性,如果要移动这类对象,就只能修改它的Transform,而不是用力。

这类游戏对象还有许多其他的独特的使用情景。

IsKinematic属性,如果启用,则外力,碰撞或关节将不再影响这个刚体。

这三种碰撞器如果勾选了IsTrigger复选框,就变成了相应的触发器了。

这是我在文档上截下来的一个图,如果读者觉得英文看起来吃力的话,就可以到Unity圣典上去看翻译的文档。

 

这个表里面包含了检测到碰撞信息所必要的碰撞组合:

从表中可以看出,两个碰撞器要想检测到碰撞信息,至少有一个是RigidbodyCollider。

这个就是我们刚才失败的关键。

我们回到Unity编辑器中,验证一下我们的猜想。

我们先给Cube1添加刚体组件。

没想到控制台打印了如下语句:

不过,这也是必须的,那么,我们将刚体组件附加在Cube2而不是Cube1上呢?

我们发现,控制台上没有打印任何语句,此时,我们可以得出如下结论:

两个物体发生碰撞,如果要检测到碰撞信息,那么其中必有一个物体既带有碰撞器,又带有刚体,且检测碰撞信息的脚本必须附着在带有刚体的碰撞器上。

到此我们就可以结束碰撞信息的检测了,剩下的2个函数就由读者自行验证一下。

下面我们来验证触发信息检测。

我们新建一个脚本,代码如下:

usingUnityEngine;

usingSystem.Collections;

publicclassTestCollider:

MonoBehaviour

{

  publicTransformcube;

  publicfloatspeed=1.0f;

  publicVector3dir=Vector3.zero;

  voidStart(){

      if(cube)

      {

        dir=cube.position-transform.position;

        dir=dir.normalized;

      }

  }

  voidUpdate(){

      transform.Translate(dir*Time.deltaTime*speed);

  }

  voidOnTriggerEnter(Colliderother)

  {

      Debug.Log("碰撞到的物体的名字是:

"+other.gameObject.name);

  }

}

我们设置Cube1为刚体碰撞器(注意,此时得将刚体组件中的UseGravity复选框的勾选去掉),然后勾选碰撞器组件中的IsTrigger复选框。

然后我们将此脚本拖拽到Cube1上面,然后将Cube2从Hierarchy面板上拖拽到脚本中的Cube选项中。

运行一下,果然有成功了:

此时,我们将脚本拖给Cube2而不拖给Cube1时,我们的结果和上次一样,没有检测到触发信息。

因此,我们可以得出这样一个结论:

两个GameObject发生碰撞,要想检测到触发信息,最少要有一个刚体碰撞器并且勾选了IsTrigger复选框,另一个最少要有一个碰撞器组件,此时检测碰撞的脚本必须附加在那个带有刚体的触发器上。

至此,触发信息的检测我们也实现了。

剩下的两个函数留给读者自行验证。

但是,由于两组函数中的参数的类型不同,我们可以通过这些参数得到一些信息。

比如OnTriggerEnter,里面的参数类型是:

Collision,根据这个参数,我们可以求得一些东西,比如接触点,具体可以看API文档关于Collision这一章,里面有一个变量contacts。

又比如

OnTriggerEnter这个函数,参数类型为:

Collider。

我们可以取得这个对象的shareMaterial这个属性,也就是物理材质。

  现在我们可以打开刚才那个官方的场景,可以在那些个刚体上绑定一个碰撞检测的脚本,然后就可以用鼠标让它与其他物体进行碰撞,可以从控制台上打印碰撞到的物体的名字。

好了,23点了,困了,下一篇,我会介绍LayerMask方面的碰撞,这里面包含摄像头的碰撞检测,并且会以这个官方的工程作为试验平台,敬请期待。

 

自己总结:

红色A,绿色B,蓝色C。

碰撞信息检测OnCollisionEnter(CollisioncollisionInfo)

1、A:

脚本(碰撞信息检测)

A可以穿过B,但检测不到碰撞。

2、A:

脚本+Rigidbody

A不能穿过B,且A会被碰撞弹飞,B纹丝不动,检测到碰撞。

B可以穿过A,但检测不到碰撞。

3、A:

脚本;B:

Rigidbody

A可以穿过B,但检测不到碰撞。

B不能穿过A,且B会被碰撞弹飞,A纹丝不动,检测到碰撞。

4、A:

脚本+Rigidbody;B:

Rigidbody

A不能穿过B,检测到碰撞,并且A可以推着B一起移动(移动结束后有轻微弹回),一起碰撞到C后推不动C,移动停止。

B不能穿过A,检测到碰撞。

5、A:

脚本+Rigidbody;B:

Rigidbody+IsTrigger

A可以闯过B,但检测不到碰撞,A不能穿过C,检测到碰撞。

B可以穿过A、C,但检测不到碰撞。

结论:

要检测到碰撞信息,两对象中必须具备刚体并都不能勾选IsTrigger,且带有碰撞信息检测脚本。

其中只有刚体对象主动去碰撞才能检测到碰撞。

不是刚体的对象可以穿过任何对象,但刚体对象不能穿过任何对象,且推不动不是刚体的对象,可以推动是刚体的对象。

注:

脚本文件名不能是关键字Collision,否则类名Collision和Unity的内置名称冲突。

触发信息检测OnTriggerEnter(Colliderother)

1、A:

脚本(触发信息检测)

A可以穿过B,但检测不到碰撞。

B可以穿过A,但检测不到碰撞。

2、A:

脚本+Rigidbody

A不能穿过B,且A会被碰撞弹飞,B纹丝不动,但检测不到碰撞。

B可以穿过A,但检测不到碰撞。

3、A:

脚本;B:

Rigidbody

A可以穿过B,但检测不到碰撞。

B不能穿过A,且B会被碰撞弹飞,A纹丝不动,但检测不到碰撞。

4、A:

脚本+Rigidbody+IsTrigger

A可以穿过B,检测到碰撞。

B可以穿过A,但检测不到碰撞。

5、A:

脚本;B:

Rigidbody+IsTrigger

A可以穿过B,但检测不到碰撞。

B可以穿过A,检测到碰撞。

6、A:

脚本+Rigidbody;B:

IsTrigger

A可以穿过B,检测到碰撞,但A不能穿过C。

B可以穿过A,但检测不到碰撞。

7、A:

脚本+IsTrigger;B:

Rigidbody

A可以穿过B,但检测不到碰撞。

B可以穿过A,检测到碰撞,但B不能穿过C。

8、A:

脚本+Rigidbody+IsTrigger;B:

IsTrigger

A可以穿过B,检测到碰撞。

B可以穿过A,但检测不到碰撞。

9、A:

脚本+Rigidbody+IsTrigger;B:

Rigidbody

A可以穿过B,检测到碰撞。

B可以穿过A,检测到碰撞,但B不能穿过C。

10、A:

脚本+Rigidbody;B:

Rigidbody+IsTrigger

A可以穿过B,检测到碰撞,但A不能穿过C。

B可以穿过A,检测到碰撞,B可以穿过C。

结论:

要检测到触发信息,两对象中必须具备刚体和勾选IsTrigger,且带有触发信息检测脚本。

其中只有刚体对象主动去碰撞才能检测到触发。

勾选了IsTrigger的对象就是触发器,可以穿过任何对象。

 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1