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.
Desafio
FácilOs 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 registraThe golem wakes up, mas seuhpcontinua 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 despawnPoint.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;
}
}
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
1Componentes, não hierarquias
Componentes pequenosUm script-base para inimigosComponentes abstratosComponentes trabalhando juntosRevisão: Torre modular4Dados Serializados
Classes SerializáveisListas no InspectorEnums no InspectorRevisão: Tabela de Loot7Máquinas de Estados
Estados como ClassesUma Máquina de EstadosTransiçõesInteligências dos InimigosRevisão: Estados da Porta10Projeto: Sobrevivente da Arena
O HeróiTipos de Inimigos5ScriptableObjects
Assets de dadosAtributos das armasConfigurações compartilhadasOndas como dadosRevisão: banco de dados de itens