Ereignisse steuern die UI
Teil des Abschnitts Spielarchitektur in Unity der Unity-Journey von Coddy. Lektion 15 von 64.
Bei Ereignissen folgt das HUD dem Spiel, während das Spiel nichts vom HUD weiß. Diese Health-Komponente verwaltet die Trefferpunkte und meldet zwei Dinge: Die Gesundheit hat sich geändert, und sie ist auf 0 gesunken. Sie 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 Testszene:
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, mithilfe des Paars OnEnable und OnDisable. Das Ereignis übergibt beide Zahlen, daher benötigt Show keine weiteren Informationen von Health. Ein GameOverScreen abonniert OnDied, um sein Panel anzuzeigen, und ein Sound für erlittenen Schaden abonniert OnChanged – beide in jeweils einem eigenen Skript. Health muss dafür nicht geändert werden. Mit Hp { get; private set; } kann das HUD die Gesundheit lesen, aber nicht ändern.
Ein Ereignis meldet Änderungen, daher hat der Balken vor dem ersten Treffer noch nichts erfahren. Er zeichnet die aktuelle Gesundheit einmal in Start. Nicht in OnEnable: Unity ruft Awake und dann OnEnable für jedes Objekt einzeln auf, und zwar in keiner festgelegten Reihenfolge. Daher kann das OnEnable des Balkens ausgeführt werden, bevor das Awake von Health Hp festgelegt hat, und der Balken würde 0 anzeigen. Bis irgendein Start ausgeführt wird, wurde jedes Awake bereits ausgeführt.
Aufgabe
EinfachLass die Waffe ihre Änderungen melden und die HUD darauf reagieren.
- Füge in
Gun.csusing System;,public event Action<int, int> OnAmmoChangedundpublic event Action<bool> OnReloadinghinzu; löse sie an den Stellen aus, an denen es in den Kommentaren steht. - Abonniere in
AmmoHud.csinOnEnabledie Ereignisse und melde dich inOnDisableab:ammoTextzeigtAmmo: 4/6an, undreloadTextwird nur während des Nachladens angezeigt. - Zeige in
Starteinmalgun.Ammoundgun.Reloadingan.
Klicke auf „Spielen“ und leere die Waffe zweimal. Klicke dann auf „Prüfen“.
Probier es selbst
using UnityEngine;
using TMPro;
public class AmmoHud : MonoBehaviour
{
public Gun gun;
public TMP_Text ammoText;
public GameObject reloadText;
}
Alle Lektionen in Spielarchitektur in Unity
1Komponenten statt Hierarchien
Kleine KomponentenEin Basis-GegnerskriptAbstrakte KomponentenZusammenwirkende KomponentenRückblick: Modulares GeschützRückblick: Zwillingskanone4Serialisierte Daten
Serialisierbare KlassenListen im InspectorEnums im InspectorRückblick: Loot-TabelleRückblick: Beute auswürfeln2Schnittstellen in Unity
IDamageableSchnittstellen und TryGetComponentGetComponentsZusammenfassung: InteraktionstasteZusammenfassung: Nächstes in Reichweite5ScriptableObjects
Daten-AssetsWaffenwerteGemeinsame EinstellungenDen Wind speichernWellen als DatenRückblick: Item-DatenbankRückblick: Im Shop einkaufen8Wiederverwendbarer Code
ErweiterungsmethodenEin generisches SingletonGenerische HilfsmethodenRückblick: FindNearest3Ereignisse
C#-Ereignisse in UnityIn OnEnable abonnierenUnityEvent-FelderEreignisse steuern die UIRückblick: Erfolgs-PopupRückblick: Popup-TimerÜbe selbstständig: Unity-Playground