Menu
CoddyTech

Zdarzenia sterują interfejsem

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

Dzięki zdarzeniom HUD podąża za grą, a gra nic nie wie o HUD-zie. Komponent Health przechowuje punkty życia i ogłasza dwie rzeczy: że zdrowie się zmieniło oraz że osiągnęło 0. Nie ma pola na pasek, tekst ani ekran końca gry, więc ten sam komponent działa na graczu, na przeciwniku, który nie ma 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 z komponentu Health. GameOverScreen subskrybuje OnDied, aby wyświetlić swój panel, a dźwięk otrzymania obrażeń subskrybuje OnChanged — każde z nich we własnym skrypcie, a komponent Health nie wymaga żadnych zmian. Hp { get; private set; } pozwala HUD-owi odczytać wartość zdrowia, ale nie pozwala jej zmienić.

Zdarzenie informuje o zmianach, więc przed pierwszym trafieniem pasek niczego nie usłyszał. Raz rysuje aktualny poziom zdrowia — w metodzie Start. Nie w OnEnable: Unity wywołuje Awake, a potem OnEnable dla każdego obiektu z osobna, w nieustalonej 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 zostały już wywołane.

challenge icon

Wyzwanie

Łatwy

Strzelnica. Spacja strzela z broni (Gun.cs), która ma maxAmmo (6) nabojów, a wystrzelenie ostatniego rozpoczyna przeładowanie trwające reloadTime (1.5) sekundy, po którym magazynek znów jest pełny. HUD jeszcze niczego z tego nie pokazuje. Spraw, by broń informowała o zmianach, a HUD nasłuchiwał tych informacji; broń nie może mieć pola dla HUD-u.

  • W Gun.cs dodaj dwa publiczne zdarzenia: OnAmmoChanged, które przekazuje liczbę nabojów i wartość maxAmmo (dwie liczby typu int), oraz OnReloading, które przekazuje wartość bool: true, gdy rozpoczyna się przeładowanie, i false, gdy się kończy. Wywołuj je w miejscach wskazanych w komentarzach.
  • W AmmoHud.cs (na HUD-zie) nasłuchuj obu zdarzeń, gdy HUD jest aktywny. ammoText pokazuje liczbę nabojów w formacie Ammo: 4/6, a reloadText (obiekt z tekstem Reloading...) jest widoczny tylko podczas przeładowania.
  • HUD od samego początku, jeszcze przed pierwszym strzałem, pokazuje prawidłowe wartości: Ammo: 6/6 i brak tekstu o przeładowaniu. Właściwości broni Ammo i Reloading zwracają bieżące wartości.
  • Jeśli HUD zostanie zniszczony, broń nadal strzela bez błędów.

Naciśnij Play, opróżnij magazynek dwa razy, a następnie naciśnij Check.

Spróbuj swoich sił

using UnityEngine;
using TMPro;

public class AmmoHud : MonoBehaviour
{
    public Gun gun;
    public TMP_Text ammoText;
    public GameObject reloadText;
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Architektura gier w Unity