Menu
CoddyTech

Um script-base para inimigos

Parte da seção Arquitetura de jogos no Unity do Journey de Unity da Coddy. Lição 2 de 50.

Inimigos compartilham a maior parte do código: pontos de vida, uma velocidade, uma forma de se mover. Esse código pode ficar em uma classe base que deriva de MonoBehaviour, e cada tipo de inimigo deriva dela. Este Enemy define seus pontos de vida em Start e caminha na direção para a qual está voltado em Update, e um Ghost altera o início para se mover duas vezes mais 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 herda os campos, então o Inspector mostra maxHp e speed em um Ghost, e ele herda Update, então caminha sem ter um Update próprio. hp é protected: Enemy e suas subclasses podem usá-lo, mas outros scripts não.

Unity encontra Start e Update pelo nome, independentemente do nível de acesso, e chama o método da classe mais derivada. Se o Start de Enemy fosse um void Start() privado e Ghost declarasse o próprio, Unity chamaria apenas o de Ghost: o de Enemy nunca seria executado, e hp permaneceria em 0 sem nenhum erro. Declarar as mensagens da classe base como protected virtual deixa isso explícito em C#: a subclasse escreve override, e base.Start() executa a parte da classe base no ponto em que você o chama. Se você omitir a chamada, a parte da classe base será ignorada, que é como uma subclasse substitui uma etapa em vez de acrescentar algo a ela.

challenge icon

Desafio

Fácil

Os monstros marcham em direção ao castelo. Enemy.cs contém o que eles têm em comum: Start define hp como maxHp e memoriza spawnPoint, e Update faz o monstro marchar pelo eixo z com speed. O Grunt é um Enemy simples e funciona. Dois tipos acrescentam uma etapa própria, e cada um perde a parte de Enemy:

  • Golem: seu Start deixa o golem 1.5 vezes maior e registra The golem wakes up, mas seu hp continua 0, porque o Unity executa o Start de Golem e nunca o de Enemy.
  • Wasp: seu Update faz com que ele se mova 1 unidade para cada lado de spawnPoint.x, mas ele ziguezagueia no mesmo lugar, porque o Unity executa o Update de Wasp e nunca o de Enemy.

Defina o Start e o Update de Enemy como protected virtual e sobrescreva-os em Golem e Wasp para que cada um execute primeiro a parte de Enemy e, em seguida, a própria. Pressione Play e depois Check.

Experimente você mesmo

using UnityEngine;

// O que todos os monstros têm em comum.
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()
    {
        // avance em direção ao castelo, ao longo do eixo z
        transform.position += Vector3.back * speed * Time.deltaTime;
    }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Arquitetura de jogos no Unity