2.7 高级敌人
2.7.1 创建敌人
只有一种敌人太单调了,我们将再添加一种新的敌人,它将继承原有敌人的大部分功能,同时增加一些新的功能。
步骤 01 在Project窗口中找到Enemy2.fbx模型文件,为其创建Prefab。
提示
可以在Project窗口中直接将FBX模型拖动到空的Prefab文件上创建敌人的Prefab。
步骤 02 创建SuperEnemy.cs脚本,使它的类继承Enemy,并重写UpdateMove方法,新敌人的移动只是简单地缓缓向前,如下所示:
[AddComponentMenu("MyGame/SuperEnemy")] public class SuperEnemy : Enemy { protected override void UpdateMove() { // 前进 m_transform.Translate(new Vector3(0, 0, -m_speed * Time.deltaTime)); } }
在SuperEnemy这个类中,只有UpdateMove()一个方法,这个方法前面使用了override标识符,表示这是一个重写的方法。虽然SuperEnemy这个类没有其他东西,但它继承了Enemy类的其他全部功能。
步骤 03 选择新敌人的prefab,将SuperEnemy脚本指定给它作为组件,然后在Inspector窗口中设置新敌人的SuperEnemy组件,增加生命至50。
步骤 04 为新敌人的prefab添加Rigidbody和Box Collider组件,并参考原有敌人的参数进行设置。因为这个新敌人的模型比较大,所以用立方体碰撞体会显得很不精确,我们可以将碰撞体缩小一些,如图2-30所示。如果希望使用精度较高的碰撞体,最好在3D软件中将其建模出来,然后将其设为Mesh碰撞体。
图2-30 设置box碰撞体
步骤 05 将新敌人的Tag设为Enemy。
2.7.2 发射子弹
将新敌人放到场景中,运行游戏,会发现新敌人缓缓向前,但不会做其他事情。接下来,我们为其添加一点新功能,使其可以向主角发射子弹,更有危险性。
步骤 01 使用rocket.fbx创建一个新的子弹Prefab,命名为EnemyRocket,再为其创建一个新的材质,使用rocket2.png作为贴图,使敌人的子弹看上去与主角的不同。
步骤 02 为敌人子弹添加Rigidbody和Box Collider组件并正确设置。
步骤 03 为敌人子弹新建一个名为EnemyRocket的Tag。
步骤 04 创建EnemyRocket.cs脚本,它将继承Rocket类的大部分功能,我们只需要略修改一下OnTriggerEnter方法,使其只能与主角飞船发生碰撞,如下所示:
[AddComponentMenu("MyGame/EnemyRocket")] public class EnemyRocket : Rocket { void OnTriggerEnter(Collider other) { if (other.tag.CompareTo("Player") ! = 0) return; Destroy(this.gameObject); } }
步骤 05 将EnemyRocket脚本指定给敌人子弹的Prefab。
步骤 06 在Inspector窗口中设置EnemyRocket组件,降低敌人子弹的移动速度,如图2-31所示。
图2-31 设置敌人子弹
步骤 07 接下来,关联新敌人和子弹,打开SuperEnemy.cs脚本,修改代码如下:
public class SuperEnemy : Enemy { public Transform m_rocket; // 子弹Prefab protected float m_fireTimer=2; // 射击计时器 protected Transform m_player; // 主角 void Awake() { GameObject obj=GameObject.FindGameObjectWithTag("Player"); // 查找主角 if ( obj! =null ) { m_player=obj.transform; } } protected override void UpdateMove() { m_fireTimer -= Time.deltaTime; if (m_fireTimer <= 0) { m_fireTimer=2; // 每2秒射击一次 if ( m_player! =null ) { // 计算子弹初始方向,使其面向主角 Vector3 relativePos = m_transform.position-m_player.position; Instantiate( m_rocket, m_transform.position, Quaternion.LookRotation(relativePos)); // 创建子弹 } } // 前进 m_transform.Translate(new Vector3(0, 0, -m_speed * Time.deltaTime)); } }
① m_fireTimer属性用来控制发射子弹的时间间隔。
② m_player属性用来指向主角的飞船。
③ Awake方法继承自MonoBehaviour,它会在游戏体实例化时执行一次,并先于Start方法。我们在这里使用FindGameObjectWithTag函数获得主角的游戏体实例。
④ Quaternion.LookRotation使子弹在初始化时朝向主角的方向。
步骤 08 选择新敌人Prefab,在Inspector窗口中选择Rocket属性,与敌人子弹的Prefab关联,如图2-32所示。
图2-32 为敌人添加子弹
将新敌人放入场景中,运行游戏,新敌人会向主角发射子弹,如图2-33所示。
图2-33 新敌人的子弹