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.
Aufgabe
EinfachEin 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.cszwei öffentliche Ereignisse hinzu:OnAmmoChanged, das die Munition undmaxAmmo(zwei ints) übergibt, undOnReloading, 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.ammoTextzeigt die Munition alsAmmo: 4/6an, undreloadText(das Objekt mit dem TextReloading...) 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/6und keinen Nachladetext. Die EigenschaftenAmmoundReloadingder 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;
}
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
1Komponenten statt Hierarchien
Kleine KomponentenEin Basisskript für GegnerAbstrakte KomponentenKomponenten im ZusammenspielRückblick: Modularer Geschützturm4Serialisierte Daten
Serialisierbare KlassenListen im InspectorEnums im InspectorRückblick: Loot-Tabelle7Zustandsautomaten
Zustände als KlassenEin ZustandsautomatÜbergängeGegner-KIWiederholung: Türzustände10Projekt: Arena-Überlebenskampf
Der HeldGegnertypen2Interfaces in Unity
IDamageableInterfaces und TryGetComponentGetComponentsRückblick: Interaktionstaste5ScriptableObjects
Daten-AssetsWaffenwerteGemeinsame EinstellungenWellen als DatenRückblick: Item-Datenbank8Wiederverwendbarer Code
ErweiterungsmethodenEin generisches SingletonGenerische HilfsmethodenRückblick: FindNearest3Ereignisse
C#-Events in UnityIn OnEnable abonnierenUnityEvent-FelderEvents steuern die UIRückblick: Achievement-Popup