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.
Desafio
FácilUm 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 emaxAmmo(dois ints), eOnReloading, 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.ammoTextmostra a munição comoAmmo: 4/6, ereloadText(o objeto com o textoReloading...) só é exibido durante uma recarga. - O HUD está correto desde o início, antes do primeiro tiro:
Ammo: 6/6e nenhum texto de recarga. As propriedadesAmmoeReloadingda 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;
}
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 itens3Eventos
Eventos de C# no UnityInscreva-se em OnEnableCampos de UnityEventEventos controlam a interfaceRevisão: janela de conquista