敌人一共有两种,一种在陆地上前进,另一种则会飞行。我们将先创建前一种,然后继承它的大部分属性和函数,略加修改完成另一种。 创建敌人的脚本Enemy.cs: using UnityEngine; using System.Collections; public class Enemy : MonoBehaviour { // 路点 public PathNode m_currentNode; // 生命 public int m_life = 15; // 最大生命值 public int m_maxLife = 15; // 移动速度 public float m_speed = 2; // 敌人的类型 public enum TYPE_ID { GROUND, AIR, } public TYPE_ID m_type = TYPE_ID.GROUND; void Update () { RotateTo(); MoveTo(); } // 转向下一个路点 public void RotateTo() { float current= this.transform.eulerAngles.y; this.transform.LookAt(m_currentNode.transform); Vector3 target = this.transform.eulerAngles; float next=Mathf.MoveTowardsAngle(current, target.y, 120 * Time.deltaTime); this.transform.eulerAngles = new Vector3(0, next, 0); } // 向下一个路点移动 public void MoveTo() { Vector3 pos1 = this.transform.position; Vector3 pos2 = m_currentNode.transform.position; // 距离子路点的距离 float dist = Vector2.Distance(new Vector2(pos1.x,pos1.z),new Vector2(pos2.x,pos2.z)); if (dist < 1.0f) { if (m_currentNode.m_next == null) { GameManager.Instance.SetDamage(1); Destroy(this.gameObject); } else m_currentNode = m_currentNode.m_next; } this.transform.Translate(new Vector3(0, 0, m_speed * Time.deltaTime)); } } 在这个脚本中,定义了敌人的一些基本属性,如生命值、移动速度、类型等,它有一个路点属性作为当前的出发点。 在MoveTo函数中,敌人向当前路点的子节点前进,当距离子路点较近时,即将子路点作为当前路点,再向下一个路点前进。注意这里计算敌人与子路点的距离时没有计算Y轴,因为我们希望空中的敌人飞到路点上方时即认为是到达该路点。当敌人走到最后的路点,即是到达我方基地,销毁自身,并使基地减少一点生命值。 在 Project窗口下的Rawdata文件夹中找到striker.fbx模型,拖入场景放到通道左侧。这是个装甲车模型,它将作为陆地上的敌人。将Enemy.cs指定给它,并设置起始路点,如图4-11所示。 图4-11 敌人组件 运行游戏,敌人会从起始点出发,沿着路点,一路前进到达我方基地,然后消失,我方基地将损失一点生命值。 接下来创建另一个飞行敌人的脚本AirEnemy.cs,它继承了Enemy脚本的大部分功能,只添加一个Fly函数,作用是当高度小于2时向上飞行。 using UnityEngine; using System.Collections; public class AirEnemy : Enemy { void Update () { RotateTo(); MoveTo(); Fly(); } public void Fly() { float flyspeed = 0; if (this.transform.position.y < 2.0f) { flyspeed = 1.0f; } this.transform.Translate(new Vector3(0, flyspeed * Time.deltaTime,0)); } } 在 Project窗口下的Rawdata文件夹中找到air.fbx模型,拖入场景放到通道左侧。这是个飞行器模型,它将作为空中的敌人。将AirEnemy.cs指定给它,并设置起始路点。运行游戏,效果如图4-12所示。 图4-12 沿着路点前进的敌人