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行代码,重新设置陨石。
运行游戏,可以看到:每当陨石与飞机碰撞之后,陨石重新位于上方不断降落。