碰撞触发器意思就是检测到两个物体碰撞的时候,触发执行脚本相关的逻辑。比如在游戏中实现两个物体相撞的时候产生爆炸的效果,那么就需要通过触发器来检测到两个物体相撞的时候,然后播放预设好的爆炸的粒子效果。
Unity引擎触发器系统有三个属性:Box Collider、Is Trigger、Rigibody
Box Collider:Unity3D的GameObject提供的基本模型才具有这个属性,表示该物体是否会和别的物体发生碰撞。
Is Trigger:BoxCollider的子选项,表示该物件是否为一个触发器。
Rigibody:选中物件,才能在菜单“Component”里,给物件添加Rigibody组件。
两Collider相碰,至少要有一个物体具有Rigibody刚体才会触发Trigger函数。当物体进来,OnTriggerEnter当然会触发。出去时,OnTriggerExit也当然触发。那么物体在进来后Destory后会如何?经过测试是:不会调用OnTriggerExit。
基本规则:脚本(含有触发判断的 OnTriggerEnter() 判断函数)和Rigibody同为一个物件的组件,Box Collider必须选中。此时两个物件的Box Collider必须为选中。而 Is Trigger选项必须“至少”有一个物件为选中(可以按逻辑来判断哪个为触发器)。 脚本中的OnTriggerEnter()可以有两种判断出发方式,此函数参数的数据类型为 Collider。 OnTriggerEnter( gameObj : Collider ),一旦触发器和Collider发生碰撞,便会触发此函数,其参数便是不包含脚本的物件的gameObject。可以通过判断其成员 name(物体在Hierarchy面板中的名字) 或 tag(物件在Inspector面板的Tag选项中的名字) 的字符串,来判定是哪个物件。
关于Unity里面的触发器的应用不仅仅可以解决物体之间的碰撞问题,常常还会用来实现游戏边界的检测辅助实现一些游戏逻辑。
1、使用Empty GameObject来实现地面或者顶部边缘的检测,比如在实现游戏主角从上面掉下来就会死掉,那么就可以在底部做一个Empty GameObject来通过触发器检测游戏主角是否掉下来。
2、游戏背景或者物体的动态生成,比如要实现一个打飞机游戏,敌人和背景都是从上往下移动,在游戏的实现逻辑里面,当上面的敌人和背景向下移动到底部的时候,你需要再生成一批敌人和背景从上面继续移动,而当这一批敌人和背景离开屏幕的时候,你还需要销毁掉它们。实现这样的一个逻辑也可以依靠触发器来辅助实现。原理如下图所示:
触发器的示例代码:
using UnityEngine; using System.Collections; // 边缘触发器,当移动的物体碰撞到之后将产生新的 public class LevelEdge : MonoBehaviour { // 碰到边缘 重新生成背景的物体 这里才是判断是否生成新的游戏物体的前提 void OnTriggerEnter(Collider other) { // 碰撞到新增触发器,将新增一套新的物体 if (other.name == "SpawnTriggerer") { switch (other.tag) { case "SecondLayer": LevelGenerator.Instance.GenerateSecondLayer(0); break; case "ThirdLayer": LevelGenerator.Instance.GenerateThirdLayer(0); break; case "FourthLayer": LevelGenerator.Instance.GenerateFourthLayer(0); break; case "Obstacles": LevelGenerator.Instance.GenerateObstacles(); break; } } // 碰撞到重设触发器,将销毁当前的物体 else if (other.name == "ResetTriggerer") { switch (other.tag) { case "SecondLayer": case "ThirdLayer": case "FourthLayer": LevelGenerator.Instance.SleepGameObject(other.transform.parent.gameObject); break; case "Obstacles": other.transform.parent.GetComponent<Obstacles>().DeactivateChild(); LevelGenerator.Instance.SleepGameObject(other.transform.parent.gameObject); break; } } // 碰撞到武器 else if (other.tag == "PowerUps") { other.GetComponent<PowerUp>().ResetThis(); } //If a torpedo is collided with this // 碰撞到炮弹 else if (other.name == "Torpedo") { other.transform.parent.gameObject.GetComponent<Torpedo>().ResetThis(); } } }