Menu
CoddyTech

A Base Enemy Script

Part of the Game Architecture in Unity section of Coddy's Unity journey. Lesson 2 of 50.

Enemies share most of their code: hit points, a speed, a way to move. That code can live in a base class that derives from MonoBehaviour, and each kind of enemy derives from it. This Enemy sets its hit points in Start and walks where it faces in Update, and a Ghost changes the start to move twice as fast:

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 inherits the fields, so the Inspector shows maxHp and speed on a Ghost, and it inherits Update, so it walks without an Update of its own. hp is protected: Enemy and its subclasses can use it, other scripts cannot.

Unity finds Start and Update by name, whatever their access, and calls the one in the most derived class. If Enemy's Start were a private void Start() and Ghost declared its own, Unity would call only Ghost's: Enemy's would never run, and hp would stay 0 with no error. Declaring the base's messages protected virtual makes this plain C#: the subclass writes override, and base.Start() runs the base's part at the point where you call it. Leave the call out and the base's part is skipped, which is how a subclass replaces a step instead of adding to it.

challenge icon

Challenge

Easy

Monsters march on the castle. Enemy.cs holds what they share: Start sets hp to maxHp and remembers spawnPoint, and Update marches the monster down the z axis at speed. The Grunt is a plain Enemy and works. Two kinds add a step of their own, and each one loses Enemy's part:

  • Golem: its Start makes the golem 1.5 times as big and logs The golem wakes up, but its hp stays 0, because Unity runs the Golem's Start and never Enemy's.
  • Wasp: its Update swings it 1 unit either side of spawnPoint.x, but it zigzags on the spot, because Unity runs the Wasp's Update and never Enemy's.

Make Enemy's Start and Update protected virtual, and override them in Golem and Wasp so each one runs Enemy's part first, then its own. Press Play, then Check.

Try it yourself

using UnityEngine;

// What every monster shares.
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()
    {
        // march on the castle, down the z axis
        transform.position += Vector3.back * speed * Time.deltaTime;
    }
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Game Architecture in Unity