Menu
CoddyTech

Eventos controlam a interface

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

Com eventos, a HUD acompanha o jogo, enquanto o jogo não sabe nada sobre a HUD. Este componente Health controla os pontos de vida e anuncia duas coisas: a vida mudou e chegou a 0. Ele não tem nenhum campo para uma barra, um texto ou uma tela de fim de jogo, então o mesmo componente funciona no jogador, em um inimigo que não tem HUD e em uma cena de teste:

public class Health : MonoBehaviour
{
    public int maxHp = 100;
    public event Action<int, int> OnChanged;
    public event Action OnDied;
    public int Hp { get; private set; }

    void Awake()
    {
        Hp = maxHp;
    }

    public void TakeDamage(int amount)
    {
        if (Hp == 0) return;
        Hp = Mathf.Max(Hp - amount, 0);
        OnChanged?.Invoke(Hp, maxHp);
        if (Hp == 0) OnDied?.Invoke();
    }
}
// HealthBar.cs, na HUD
public Health health;
public Image bar;

void OnEnable() { health.OnChanged += Show; }
void OnDisable() { health.OnChanged -= Show; }

void Start()
{
    Show(health.Hp, health.maxHp);
}

void Show(int hp, int max)
{
    bar.fillAmount = (float)hp / max;
}

A barra só escuta enquanto está ativa, usando o par OnEnable e OnDisable. O evento passa os dois números, então Show não precisa de mais nada do componente Health. Uma GameOverScreen se inscreve em OnDied para exibir seu painel, e um som de dano se inscreve em OnChanged, cada um em seu próprio script, sem que o componente Health precise mudar por causa deles. Hp { get; private set; } permite que a HUD leia a vida, mas não a altere.

Um evento informa sobre mudanças, então, antes do primeiro golpe, a barra ainda não recebeu nenhuma informação. Ela desenha a vida atual uma vez, em Start. Não em OnEnable: o Unity chama Awake e depois OnEnable objeto por objeto, sem uma ordem garantida, então o OnEnable da barra pode ser executado antes de o Awake do componente Health definir Hp, e a barra exibiria 0. Quando qualquer método Start é executado, todos os métodos Awake já foram executados.

challenge icon

Desafio

Fácil

Um estande de tiro. A tecla Espaço dispara a arma (Gun.cs), que comporta maxAmmo (6) tiros, e disparar o último inicia uma recarga de reloadTime (1.5) segundos que a enche novamente. O HUD ainda não mostra nada disso. Faça a arma anunciar suas mudanças e o HUD escutá-las; a arma não recebe nenhum campo para o HUD.

  • Em Gun.cs, adicione dois eventos públicos: OnAmmoChanged, que passa a munição e maxAmmo (dois ints), e OnReloading, que passa um bool: true quando uma recarga começa, false quando termina. Dispare-os nos locais indicados pelos comentários.
  • Em AmmoHud.cs (no HUD), escute os dois eventos enquanto o HUD estiver ativo. ammoText mostra a munição como Ammo: 4/6, e reloadText (o objeto com o texto Reloading...) só é exibido durante uma recarga.
  • O HUD está correto desde o início, antes do primeiro tiro: Ammo: 6/6 e nenhum texto de recarga. As propriedades Ammo e Reloading da arma fornecem os valores atuais.
  • Se o HUD for destruído, a arma continua disparando sem erros.

Pressione Play, esvazie a arma duas vezes e, em seguida, pressione Check.

Experimente você mesmo

using UnityEngine;
using TMPro;

public class AmmoHud : MonoBehaviour
{
    public Gun gun;
    public TMP_Text ammoText;
    public GameObject reloadText;
}
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