Menu
CoddyTech

Un script base para enemigos

Parte de la sección Arquitectura de juegos en Unity del Journey de Unity de Coddy. Lección 2 de 50.

Los enemigos comparten la mayor parte de su código: puntos de vida, una velocidad y una forma de moverse. Ese código puede estar en una clase base que deriva de MonoBehaviour, y cada tipo de enemigo deriva de ella. Este Enemy establece sus puntos de vida en Start y camina hacia donde está orientado en Update, mientras que un Ghost cambia el inicio para moverse el doble de rápido:

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 hereda los campos, así que el Inspector muestra maxHp y speed en un Ghost, y también hereda Update, por lo que camina sin tener su propio Update. hp es protected: Enemy y sus subclases pueden usarlo; otros scripts no.

Unity encuentra Start y Update por su nombre, independientemente de su nivel de acceso, y llama al de la clase más derivada. Si el Start de Enemy fuera un void Start() privado y Ghost declarara el suyo, Unity llamaría solo al de Ghost: el de Enemy nunca se ejecutaría y hp permanecería en 0 sin que se produjera ningún error. Declarar los mensajes de la clase base como protected virtual hace que esto sea explícito en C#: la subclase escribe override y base.Start() ejecuta la parte de la clase base en el punto donde lo llamas. Si omites la llamada, se omite la parte de la clase base; así es como una subclase reemplaza un paso en vez de añadirle algo.

challenge icon

Desafío

Fácil

Los monstruos marchan hacia el castillo. Enemy.cs contiene lo que comparten: Start establece hp en maxHp y recuerda spawnPoint, y Update hace que el monstruo marche por el eje z a speed. Grunt es un Enemy normal y funciona. Dos tipos añaden un paso propio, y cada uno pierde la parte de Enemy:

  • Golem: su Start hace que el golem sea 1.5 veces más grande y registra The golem wakes up, pero su hp permanece en 0, porque Unity ejecuta el Start de Golem y nunca el de Enemy.
  • Wasp: su Update lo mueve 1 unidad a cada lado de spawnPoint.x, pero zigzaguea en el sitio, porque Unity ejecuta el Update de Wasp y nunca el de Enemy.

Haz que Start y Update de Enemy sean protected virtual, y sobrescríbelos en Golem y Wasp para que cada uno ejecute primero la parte de Enemy y después la suya. Pulsa Play y después Check.

Pruébalo tú mismo

using UnityEngine;

// Lo que comparten todos los monstruos.
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()
    {
        // avanza hacia el castillo por el eje z descendente
        transform.position += Vector3.back * speed * Time.deltaTime;
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Arquitectura de juegos en Unity