Menu
CoddyTech

Zdarzenia sterują UI

Część sekcji Architektura gier w Unity ścieżki Unity w Coddy. Lekcja 15 z 64.

Dzięki zdarzeniom HUD podąża za grą, podczas gdy gra nie wie nic o HUD-zie. Ten komponent Health przechowuje punkty zdrowia i informuje o dwóch rzeczach: zdrowie się zmieniło oraz osiągnęło 0. Nie ma pola na pasek, tekst ani ekran końca gry, więc ten sam komponent działa u gracza, u przeciwnika bez HUD-u oraz w scenie testowej:

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;
}

Pasek nasłuchuje tylko wtedy, gdy jest aktywny, dzięki parze OnEnable i OnDisable. Zdarzenie przekazuje obie liczby, więc Show nie potrzebuje niczego więcej od komponentu Health. GameOverScreen subskrybuje OnDied, aby wyświetlić swój panel, a dźwięk obrażeń subskrybuje OnChanged — każde z nich we własnym skrypcie. Komponent Health nie wymaga żadnych zmian. Hp { get; private set; } pozwala HUD-owi odczytać poziom zdrowia, ale nie go zmieniać.

Zdarzenie informuje o zmianach, więc przed pierwszym trafieniem pasek niczego jeszcze nie usłyszał. Raz rysuje aktualny poziom zdrowia — w metodzie Start. Nie w OnEnable: Unity wywołuje Awake, a potem OnEnable dla poszczególnych obiektów, bez gwarantowanej kolejności, więc OnEnable paska może wykonać się przed Awake komponentu Health, które ustawia Hp, a wtedy pasek pokazałby 0. Zanim wykona się jakakolwiek metoda Start, wszystkie metody Awake już się wykonają.

challenge icon

Wyzwanie

Łatwy

Spraw, by broń informowała o swoich zmianach, a HUD nasłuchiwał.

  1. W Gun.cs dodaj using System;, public event Action<int, int> OnAmmoChanged i public event Action<bool> OnReloading; wywołuj je w miejscach wskazanych w komentarzach.
  2. W AmmoHud.cs zasubskrybuj zdarzenia w OnEnable i anuluj subskrypcję w OnDisable: ammoText wyświetla Ammo: 4/6, a reloadText jest widoczny tylko podczas przeładowywania.
  3. W Start jednorazowo wyświetl gun.Ammo i gun.Reloading.

Naciśnij „Graj” i opróżnij magazynek dwa razy. Następnie naciśnij „Sprawdź”.

Spróbuj swoich sił

using UnityEngine;
using TMPro;

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

Wszystkie lekcje w sekcji Architektura gier w Unity

Poćwicz samodzielnie: Edytor online Unity