Unity 3D\2D手机游戏开发:从学习到产品(第3版)
上QQ阅读APP看书,第一时间看更新

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 新敌人的子弹