Unity 4.3游戏开发项目实战(C#、JavaScript版本)
上QQ阅读APP看书,第一时间看更新

2.6 碰撞检测

在Unity3D中,要实现碰撞检测,需要满足两个必要条件:第一个条件是碰撞的双方游戏对象必须具有碰撞体;第二个条件是运动的游戏对象必须具有刚体属性。

2.6.1 炮弹与陨石碰撞检测

在炮弹与陨石的碰撞检测中,将炮弹当做运动的游戏对象,因此需要在炮弹中不仅设置碰撞体,还要设置刚体。

1.添加炮弹碰撞体、刚体和标签

首先需要为炮弹设置碰撞体。

在图2-73中,单击菜单“Component”→“Physics”→“Capsule Collider”命令,为炮弹新建一个胶囊碰撞体。

图2-73 设置胶囊碰撞体

新建炮弹的胶囊碰撞体之后,在游戏场景Scene中,查看projectile对象,由于炮弹中添加了声音,声音图标遮挡了炮弹,如图2-74所示。

图2-74 游戏场景中的声音图标

在图2-75中,单击“Gizmos”,在出现的下拉菜单中设置滑动按钮到最左边的位置,以便隐藏声音图标。

图2-75 隐藏声音图标

在图2-76中,设置胶囊碰撞体的相关参数,以便胶囊碰撞体刚好围绕炮弹的图片。设置Center参数均为0, Radius=0.09, Height=0.72, Direction则设置为Y-Axis,并注意勾选Is Trigger属性。

图2-76 设置胶囊碰撞体

为炮弹添加了胶囊碰撞体之后,还需要为炮弹添加刚体。

单击菜单“Component”→“Physics”→“Rigidbody”命令,为炮弹新建一个刚体,以便炮弹具有物理属性,如图2-77所示。

图2-77 添加刚体

在如图2-78所示的设置刚体属性中,将Use Gravity非勾选,并设置Constraints的参数中的Freeze Position:Z轴勾选;Freeze Rotation:X、Y、Z轴勾选。

图2-78 设置刚体

为方便后续步骤的碰撞检测,还需要设置炮弹的标签。

在检视器中,单击标签Tag右边的下拉菜单,在出现的下拉菜单选择“Add Tag”命令,如图2-79所示。

图2-79 添加标签

在打开的如图2-80所示的界面中,输入标签 “projectile”,然后在如图2-81所示的界面中,选择刚才新建的标签projectile,这样炮弹就具有了标签projectile。

图2-80 输入标签

图2-81 选择标签

成功设置炮弹的碰撞体和刚体之后,在层次Hierarchy窗格中选择projectile对象,拖放到项目Project窗格中的预制件projectile之上,更新预制件projectile,如图2-82所示。

图2-82 更新炮弹预制件

2.设置陨石碰撞体

在图2-83中,单击菜单“Component”→“Physics”→“Box Collider”命令,为陨石新建一个立方体碰撞体,然后勾选Is Trigger属性。

图2-83 设置立方体碰撞体

这样,就为陨石也设置了碰撞体。

3.炮弹与陨石碰撞检测

要实现炮弹与陨石的碰撞检测,这里需要说明的是,还有一个最大的前提就是炮弹与陨石必须处在同一个平面上,即Position参数中的Z=0。

对于C#开发者来说,在RockController.cs中添加碰撞检测的代码,见代码2-21。

代码2-21 RockController的C#代码

1: using UnityEngine;
2: using System.Collections;
3:
4: public class RockController : MonoBehaviour
5: {
6:
7:   public float speed=2.0f;
8:
9:   void Update()
10:  {
11:     transform.Translate(0, -speed*Time.deltaTime,0);
12: }
13: }
14:
15: function OnTriggerEnter (other : Collider)
16: {
17:   if(other.tag=="projectile")
18:   {
19:    transform.position=new Vector3(Random.Range(-2.1f,2.1f),3.5f,0);
20:    Destroy(other.gameObject);
21:
22:   }
23: }

在上述C#代码中,与代码2-13相比较,添加了第15行到第23行的碰撞检测代码。其中第17行代码检测碰撞陨石的对象是否是炮弹,如果是炮弹,则执行第19行、第20行代码。第19行代码重新设置陨石,第20行代码则销毁炮弹。

对于JavaScript开发者来说,在rockController.js中添加碰撞检测的代码,见代码2-22。

代码2-22 rockController的JavaScript代码

1: var speed:float=2.0f;
2:
3: function Update()
4: {
5:   transform.Translate(0, -speed*Time.deltaTime,0);
6: }
7:
8: function OnTriggerEnter (other : Collider)
9: {
10:   if(other.tag=="projectile")
11:   {
12:    transform.position=new Vector3(Random.Range(-2.1f,2.1f),3.5f,0);
13:    Destroy(other.gameObject);
14:
15:   }
16:}

在上述JavaScript代码中,与代码2-14相比较,添加了第8行到第16行的碰撞检测代码。其中第10行代码检测碰撞陨石的对象是否是炮弹,如果是炮弹,则执行第12行、第13行代码。第12行代码重新设置陨石,第13行代码则销毁炮弹。

重新设置飞机Position的Y=-0.53,让飞机处于屏幕的底部。运行游戏,可以看到:每当炮弹击中陨石之后,炮弹被销毁,陨石重新位于上方不断降落。

2.6.2 飞机与陨石碰撞检测

在飞机与陨石的碰撞检测中,需要将陨石当做运动的游戏对象,因此需要在陨石中添加刚体。

1.添加陨石刚体

单击菜单“Component”→“Physics”→“Rigidbody”命令,为陨石新建一个刚体,以便陨石具有物理属性,如图2-84所示。

图2-84 添加刚体

在如图2-85所示的设置刚体属性中,设置属性Use Gravity为非勾选,并设置Constraints参数中的Freeze Position:Z轴勾选;Freeze Rotation:X、Y、Z轴勾选。

图2-85 设置刚体

2.添加飞机碰撞体、标签

在图2-86中,单击菜单“Component”→“Physics”→“Box Collider”命令,为陨石新建一个立方体碰撞体,然后勾选Is Trigger属性。

图2-86 添加飞机的立方体碰撞体

然后为飞机添加标签Player,并选择飞机的标签为Player。

3.飞机与陨石碰撞检测

要实现飞机与陨石的碰撞检测,这里还需要说明的是,飞机与陨石必须处在同一个平面上,即Position参数的Z=0。

对于C#开发者来说,在RockController.cs中添加飞机与陨石的碰撞检测的代码,见代码2-23。

代码2-23 RockController的C#代码

1: using UnityEngine;
2: using System.Collections;
3:
4: public class RockController : MonoBehaviour
5: {
6:
7:   public float speed=2.0f;
8:
9:   void Update()
10:  {
11:     transform.Translate(0, -speed*Time.deltaTime,0);
12: }
13: }
14:
15: function OnTriggerEnter (other : Collider)
16: {
17:   if(other.tag=="projectile")
18:   {
19:    transform.position=new Vector3(Random.Range(-2.1f,2.1f),3.5f,0);
20:    Destroy(other.gameObject);
21:
22:   }
23:
24:   if(other.tag=="Player")
25:    {
26:
27:      transform.position=new Vector3(Random.Range(-2.1f,2.1f),3.5f,0);
28:    }
29: }

在上述C#代码中,与代码2-21相比较,添加了第24行到第28行的飞机与陨石碰撞检测的代码。其中第24行代码检测碰撞陨石的对象是否是飞机,如果是飞机,则执行第27行代码,重新设置陨石。

对于JavaScript开发者来说,在rockController.js中添加飞机与陨石碰撞检测的代码,见代码2-24。

代码2-24 rockController的JavaScript代码

1: var speed:float=2.0f;
2:
3: function Update()
4: {
5:   transform.Translate(0, -speed*Time.deltaTime,0);
6: }
7:
8: function OnTriggerEnter (other : Collider)
9: {
 10:   if(other.tag=="projectile")
 11:   {
12:    transform.position=new Vector3(Random.Range(-2.1f,2.1f),3.5f,0);
13:    Destroy(other.gameObject);
14:
15:   }
16:
17:   if(other.tag=="Player")
18:   {
19:
20:     transform.position=new Vector3(Random.Range(-2.1f,2.1f),3.5f,0);
21:    }
22: }

在上述JavaScript代码中,与代码2-22相比较,添加了第17行到第21行的飞机与陨石碰撞检测的代码。其中第17行代码检测碰撞陨石的对象是否是飞机,如果是飞机,则执行第20行代码,重新设置陨石。

运行游戏,可以看到:每当陨石与飞机碰撞之后,陨石重新位于上方不断降落。