Menu
CoddyTech

Los eventos controlan la interfaz

Parte de la sección Arquitectura de juegos en Unity del Journey de Unity de Coddy. Lección 13 de 50.

Con los eventos, el HUD sigue el juego mientras el juego no sabe nada del HUD. Este componente Health tiene los puntos de vida y anuncia dos cosas: que la salud ha cambiado y que ha llegado a 0. No tiene ningún campo para una barra, un texto ni una pantalla de fin de partida, así que el mismo componente funciona en el jugador, en un enemigo que no tiene HUD y en una escena de prueba:

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, en el 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;
}

La barra escucha solo mientras está activa, con el par OnEnable y OnDisable. El evento pasa ambos números, así que Show no necesita nada más de Health. Un GameOverScreen se suscribe a OnDied para mostrar su panel, y un sonido de daño se suscribe a OnChanged, cada uno en su propio script; Health no cambia para ninguno de ellos. Hp { get; private set; } permite que el HUD lea la salud, pero no que la cambie.

Un evento informa de los cambios, así que antes del primer golpe la barra no ha recibido ninguna notificación. Dibuja la salud actual una vez, en Start. No en OnEnable: Unity llama a Awake y luego a OnEnable para cada objeto, sin un orden garantizado, así que el OnEnable de la barra puede ejecutarse antes de que el Awake de Health haya establecido Hp, y la barra mostraría 0. Para cuando se ejecuta cualquier Start, ya se han ejecutado todos los Awake.

challenge icon

Desafío

Fácil

Un campo de tiro. La barra espaciadora dispara el arma (Gun.cs), que tiene maxAmmo (6) disparos; al disparar el último, comienza una recarga de reloadTime (1.5) segundos que vuelve a llenarla. La interfaz aún no muestra nada de esto. Haz que el arma anuncie sus cambios y que la interfaz los escuche; el arma no debe tener ningún campo para la interfaz.

  • En Gun.cs, añade dos eventos públicos: OnAmmoChanged, que pasa la munición y maxAmmo (dos enteros), y OnReloading, que pasa un booleano: true cuando comienza una recarga y false cuando termina. Invócalos donde lo indiquen los comentarios.
  • En AmmoHud.cs (en la interfaz), escucha ambos eventos mientras la interfaz esté activa. ammoText muestra la munición como Ammo: 4/6, y reloadText (el objeto con el texto Reloading...) solo se muestra durante una recarga.
  • La interfaz muestra los valores correctos desde el principio, antes del primer disparo: Ammo: 6/6 y ningún texto de recarga. Las propiedades Ammo y Reloading del arma proporcionan los valores actuales.
  • Si se destruye la interfaz, el arma sigue disparando sin errores.

Pulsa Play, vacía el arma dos veces y después pulsa Check.

Pruébalo tú mismo

using UnityEngine;
using TMPro;

public class AmmoHud : MonoBehaviour
{
    public Gun gun;
    public TMP_Text ammoText;
    public GameObject reloadText;
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Arquitectura de juegos en Unity