基础敌人脚本
本课属于 Coddy Unity 学习旅程的“Unity 游戏架构”单元。第 2 课,共 64 课。
在 C# 中,一个类可以派生自另一个类:class Ghost : Enemy 会获得 Enemy 的所有字段和方法,并添加自己的内容。基类标记为 virtual 的方法可以在子类中用 override 替换,而 base.Describe() 会在新方法中运行基类的版本。下面是普通的 C# 代码:
class Enemy
{
protected int hp = 3;
public virtual string Describe()
{
return "Enemy with " + hp + " hp";
}
}
class Ghost : Enemy
{
public override string Describe()
{
return base.Describe() + ", see-through";
}
}Ghost 的 Describe() 会返回 Enemy with 3 hp, see-through。protected 表示 Enemy 及其子类可以使用 hp,其他类则不能。
在 Unity 中,敌人共享大部分代码:生命值、速度和移动方式。这些代码放在一个基类中,该基类派生自 MonoBehaviour,每种敌人都从这个基类派生。这个 Enemy 会在 Start 中设置生命值,并在 Update 中朝面向的方向移动;Ghost 则会修改启动逻辑,使移动速度变为两倍:
public class Enemy : MonoBehaviour
{
public int maxHp = 3;
public float speed = 2f;
protected int hp;
protected virtual void Start()
{
hp = maxHp;
}
protected virtual void Update()
{
transform.Translate(Vector3.forward * speed * Time.deltaTime);
}
}public class Ghost : Enemy
{
protected override void Start()
{
base.Start();
speed *= 2f;
}
}Ghost 会继承这些字段,因此 Inspector 会在 Ghost 上显示 maxHp 和 speed;它也会继承 Update,因此即使没有自己的 Update,也会移动。hp 是 protected:Enemy 及其子类可以使用它,其他脚本则不能。
Unity 会按名称查找 Start 和 Update,无论它们的访问级别如何,并调用派生层级最深的类中的方法。如果 Enemy 的 Start 是一个 private void Start(),而 Ghost 声明了自己的 Start,Unity 就只会调用 Ghost 的方法:Enemy 的方法不会运行,hp 会保持为 0,而且不会报错。将基类的这些消息声明为 protected virtual,就能使用普通的 C# 机制:子类写上 override,而 base.Start() 会在你调用它的位置运行基类中的部分代码。如果省略这个调用,基类中的部分就会被跳过。这样,子类就能替换某个步骤,而不是在原有步骤上添加内容。
挑战
简单让 Golem 和 Wasp 先运行 Enemy 中的部分,再运行各自的部分。
- 在
Enemy中,在void Start()和void Update()前面写上protected virtual。 - 在
Golem中,将其改为protected override void Start(),并将base.Start();作为第一行。 - 在
Wasp中,将其改为protected override void Update(),并将base.Update();作为第一行。
按下 Play:石像怪会以满血状态行进,黄蜂会一边行进一边 zigzag。然后点击 Check。
亲手试试
using UnityEngine;
// 所有怪物共有的特性。
public class Enemy : MonoBehaviour
{
public int maxHp = 4;
public float speed = 1.5f;
protected int hp;
protected Vector3 spawnPoint;
void Start()
{
hp = maxHp;
spawnPoint = transform.position;
}
void Update()
{
// 沿 z 轴向城堡进军
transform.position += Vector3.back * speed * Time.deltaTime;
}
}
Unity 游戏架构中的所有课
自己练习: Unity 在线编辑器