Menu
CoddyTech

Events steuern die UI

Teil des Abschnitts Spielarchitektur in Unity der Unity-Journey von Coddy. Lektion 13 von 50.

Mit Ereignissen folgt das HUD dem Spiel, während das Spiel nichts vom HUD weiß. Dieses Health besitzt die Lebenspunkte und meldet zwei Dinge: Die Gesundheit hat sich geändert und sie ist auf 0 gesunken. Es hat kein Feld für einen Balken, einen Text oder einen Game-over-Bildschirm, daher funktioniert dieselbe Komponente auf dem Spieler, auf einem Gegner ohne HUD und in einer Testszenen:

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, auf dem 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;
}

Der Balken lauscht nur, solange er aktiv ist, mit dem OnEnable- und OnDisable-Paar. Das Ereignis übergibt beide Zahlen, daher benötigt Show nichts Weiteres von Health. Ein GameOverScreen abonniert OnDied, um sein Panel anzuzeigen, und ein Schadensgeräusch abonniert OnChanged, jeweils in einem eigenen Skript; Health muss sich dafür nicht ändern. Hp { get; private set; } ermöglicht dem HUD, die Gesundheit auszulesen, aber nicht zu ändern.

Ein Ereignis meldet Änderungen, daher hat der Balken vor dem ersten Treffer noch nichts gehört. Er zeichnet die aktuelle Gesundheit einmal in Start. Nicht in OnEnable: Unity ruft Awake und dann OnEnable für jedes Objekt einzeln und in keiner festgelegten Reihenfolge auf. Daher kann OnEnable des Balkens ausgeführt werden, bevor Awake von Health Hp gesetzt hat, und der Balken würde 0 anzeigen. Wenn irgendein Start ausgeführt wird, wurde jedes Awake bereits ausgeführt.

challenge icon

Aufgabe

Einfach

Ein Schießstand. Mit der Leertaste wird die Waffe abgefeuert (Gun.cs), die maxAmmo (6) Schuss fasst. Wird der letzte Schuss abgefeuert, beginnt ein Nachladen von reloadTime (1.5) Sekunden, das die Munition wieder auffüllt. Das HUD zeigt davon noch nichts an. Lass die Waffe ihre Änderungen melden und das HUD darauf reagieren; die Waffe erhält kein Feld für das HUD.

  • Füge in Gun.cs zwei öffentliche Ereignisse hinzu: OnAmmoChanged, das die Munition und maxAmmo (zwei ints) übergibt, und OnReloading, das einen bool übergibt: true, wenn das Nachladen beginnt, und false, wenn es endet. Löse die Ereignisse an den Stellen aus, die in den Kommentaren angegeben sind.
  • Höre in AmmoHud.cs (auf dem HUD) auf beide Ereignisse, solange das HUD aktiv ist. ammoText zeigt die Munition als Ammo: 4/6 an, und reloadText (das Objekt mit dem Text Reloading...) wird nur während des Nachladens angezeigt.
  • Das HUD zeigt von Anfang an die richtigen Werte an, also noch vor dem ersten Schuss: Ammo: 6/6 und keinen Nachladetext. Die Eigenschaften Ammo und Reloading der Waffe liefern die aktuellen Werte.
  • Wird das HUD zerstört, feuert die Waffe ohne Fehler weiter.

Drücke Play, leere die Waffe zweimal und klicke dann auf Check.

Probier es selbst

using UnityEngine;
using TMPro;

public class AmmoHud : MonoBehaviour
{
    public Gun gun;
    public TMP_Text ammoText;
    public GameObject reloadText;
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Spielarchitektur in Unity