Menu
CoddyTech

Componentes abstratos

Parte da seção Arquitetura de Jogos no Unity do Journey de Unity da Coddy. Lição 3 de 64.

Algumas classes base descrevem um tipo de coisa que nunca existe por si só. Toda arma dispara, mas uma arma que não é nem uma pistola nem uma espingarda não tem como disparar. Marque essa classe como abstract e declare cada etapa que suas subclasses devem implementar como um método abstrato, sem corpo:

public abstract class Weapon : MonoBehaviour
{
    public int shots;

    public void Pull()
    {
        shots++;
        Fire();
    }

    protected abstract void Fire();
}
public class Shotgun : Weapon
{
    public GameObject pelletPrefab;

    protected override void Fire()
    {
        for (int i = -1; i <= 1; i++)
        {
            Instantiate(pelletPrefab, transform.position + transform.right * i * 0.3f, transform.rotation);
        }
    }
}

Uma subclasse que não implementa Fire não compila: CS0534, 'Pistol' does not implement inherited abstract member 'Weapon.Fire()'. O Unity também se recusa a adicionar um script abstrato a um objeto. Arraste Weapon para um objeto e a mensagem será Can't add script behaviour 'Weapon'. The script class can't be abstract!, já que o Unity não poderia criar uma Weapon sem Fire.

Outros scripts ainda funcionam com o tipo base. GetComponent<Weapon>() retorna qualquer subclasse que esteja no objeto, e Pull() executa o Fire dessa subclasse:

// Player.cs
private Weapon weapon;

void Start()
{
    weapon = GetComponent<Weapon>();
}

void Update()
{
    if (Mouse.current.leftButton.wasPressedThisFrame)
    {
        weapon.Pull();
    }
}

Troque o componente Shotgun por um Pistol e o script Player continuará igual.

challenge icon

Desafio

Fácil

Torne Monster abstrata e faça a torre eletrocutar cada tipo de monstro.

  1. Em Monster, escreva public abstract class Monster e protected abstract void React();, sem corpo.
  2. Agora, o compilador aponta para Imp: adicione protected override void React() que soma Vector3.forward * 2f à posição dele.
  3. Em Tower, dentro do loop, chame Zap() em target.GetComponent<Monster>().

Pressione “Jogar” e Espaço: os slimes encolhem, o imp salta para trás. Depois, pressione “Verificar”.

Experimente você mesmo

using UnityEngine;

// O que todos os monstros têm em comum.
public class Monster : MonoBehaviour
{
    public int hp = 3;

    public void Zap()
    {
        hp--;
        if (hp <= 0)
        {
            Destroy(gameObject);
        }
        else
        {
            React();
        }
    }

    // Como esse tipo de monstro reage a um choque ao qual sobrevive.
    protected virtual void React()
    {
    }
}

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

Pratique por conta própria: Playground de Unity