Menu
CoddyTech

Events Drive the UI

Part of the Game Architecture in Unity section of Coddy's Unity journey. Lesson 13 of 50.

With events, the HUD follows the game while the game knows nothing of the HUD. This Health owns the hit points and announces two things: the health changed, and it reached 0. It has no field for a bar, a text or a game-over screen, so the same component works on the player, on an enemy that has no HUD, and in a test scene:

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, on the 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;
}

The bar listens only while it is active, with the OnEnable and OnDisable pair. The event passes both numbers, so Show needs nothing else from the Health. A GameOverScreen subscribes to OnDied to show its panel and a hurt sound subscribes to OnChanged, each in its own script, and the Health does not change for any of them. Hp { get; private set; } lets the HUD read the health but not change it.

An event reports changes, so before the first hit the bar has heard nothing. It draws the current health once, in Start. Not in OnEnable: Unity calls Awake and then OnEnable object by object, in no promised order, so the bar's OnEnable can run before the Health's Awake has set Hp, and the bar would show 0. By the time any Start runs, every Awake has run.

challenge icon

Challenge

Easy

A shooting range. Space fires the gun (Gun.cs), which holds maxAmmo (6) shots, and firing the last one starts a reload of reloadTime (1.5) seconds that fills it again. The HUD shows none of this yet. Make the gun announce its changes and the HUD listen; the gun gets no field for the HUD.

  • In Gun.cs, add two public events: OnAmmoChanged, which passes the ammo and maxAmmo (two ints), and OnReloading, which passes a bool: true when a reload starts, false when it ends. Raise them where the comments say.
  • In AmmoHud.cs (on the HUD), listen to both events while the HUD is active. ammoText shows the ammo as Ammo: 4/6, and reloadText (the object with the text Reloading...) is shown only during a reload.
  • The HUD is right from the start, before the first shot: Ammo: 6/6 and no reload text. The gun's Ammo and Reloading properties give the current values.
  • If the HUD is destroyed, the gun keeps firing without errors.

Press Play, empty the gun twice, then Check.

Try it yourself

using UnityEngine;
using TMPro;

public class AmmoHud : MonoBehaviour
{
    public Gun gun;
    public TMP_Text ammoText;
    public GameObject reloadText;
}
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Game Architecture in Unity