Menu
CoddyTech

IDamageable

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

Uma interface é uma lista de métodos que uma classe promete ter, sem código dentro deles. Classes que não têm mais nada em comum podem fazer a mesma promessa. Em C# puro:

interface IGreeter
{
    string Greet();
}

class Robot : IGreeter
{
    public string Greet() { return "Beep"; }
}

class Cat : IGreeter
{
    public string Greet() { return "Meow"; }
}

Uma variável do tipo IGreeter pode conter um Robot ou um Cat, e greeter.Greet() executa o método do objeto que ela contém. Uma classe que lista IGreeter, mas não tem um Greet() público, não compila.

Em um jogo, muitas coisas podem sofrer dano e têm pouco mais em comum: o jogador tem pontos de vida, uma caixa quebra no primeiro golpe. Uma classe base compartilhada as forçaria a pertencer à mesma família. Uma interface dá nome à única coisa que elas têm em comum, e cada script a implementa à sua maneira:

public interface IDamageable
{
    void TakeDamage(int amount);
}
public class PlayerHealth : MonoBehaviour, IDamageable
{
    public int hp = 10;

    public void TakeDamage(int amount)
    {
        hp -= amount;
        Debug.Log("Ouch! hp: " + hp);
    }
}
public class Crate : MonoBehaviour, IDamageable
{
    public void TakeDamage(int amount)
    {
        Destroy(gameObject);
    }
}

Um script ainda tem uma classe base, MonoBehaviour, e lista as interfaces depois dela. A interface fica em um arquivo próprio, IDamageable.cs, e não deriva de MonoBehaviour: ela não é um componente e nunca é adicionada sozinha a um objeto. Uma classe que a lista precisa ter um TakeDamage(int) público, ou não compila.

O que quer que cause o dano pede a interface, não uma classe:

// Fireball.cs
void OnCollisionEnter(Collision collision)
{
    IDamageable target = collision.gameObject.GetComponent<IDamageable>();
    if (target != null)
    {
        target.TakeDamage(3);
    }
    Destroy(gameObject);
}

A bola de fogo causa dano ao jogador e quebra caixas com as mesmas linhas, e um tipo de alvo adicionado depois não exige nenhuma alteração aqui. O Unity não mostra no Inspector um campo de tipo interface, então os scripts mantêm um GameObject ou componente e pedem a ele a interface, como faz a bola de fogo.

challenge icon

Desafio

Fácil

Faça o boneco de neve, o sino e o espantalho implementarem IDamageable, para que o martelo os atinja.

  1. Snowman: TakeDamage o encolhe em 0.25f * amount em cada eixo; quando chegar a 0.5 ou menos, destrua-o.
  2. Bell: registre Dong uma vez por ponto e adicione amount a rings.
  3. Scarecrow: somente o primeiro golpe executa transform.Rotate(0f, 0f, 90f);.
  4. Em Slam, chame TakeDamage(power) em cada collider que tiver IDamageable.

Pressione “Jogar” e golpeie cada um. Em seguida, clique em “Verificar”.

Experimente você mesmo

using UnityEngine;

public class Snowman : MonoBehaviour
{
}

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

Pratique por conta própria: Playground de Unity