Erreiche die Basis
Lektion 3 von 18 im Kurs Unity-Spiel: Tower Defense von Coddy.
Ein Gegner, der den letzten Wegpunkt erreicht, hat die Basis erreicht: Der Spieler verliert Leben und der Gegner verschwindet. Die Leben gehören zum GameManager, der sie auf dem Bildschirm anzeigt. Der Gegner sollte keine Referenz auf den GameManager benötigen, um dies zu melden: Bald werden Gegner dutzendweise aus einem Prefab erstellt, und ein Prefab kann nicht auf ein Objekt in der Szene verweisen.
Ein statisches Ereignis löst beides. Es gehört zur Klasse Enemy, nicht zu einem einzelnen Gegner, sodass der GameManager es einmal abonniert und von jedem Gegner benachrichtigt wird, auch von später erzeugten. Jeder Gegner löst es mit sich selbst als Argument aus, sodass der Listener lesen kann, welche Art durchgekommen ist. Eine Münze in einem Platformer meldet es auf dieselbe Weise:
public class Coin : MonoBehaviour
{
public static event Action<Coin> Collected;
public int value = 1;
void OnTriggerEnter(Collider other)
{
Collected?.Invoke(this);
Destroy(gameObject);
}
}// ScoreBoard.cs
void OnEnable()
{
Coin.Collected += AddCoin;
}
void OnDisable()
{
Coin.Collected -= AddCoin;
}
void AddCoin(Coin coin)
{
score += coin.value;
}Ein statisches Ereignis lebt so lange wie das Spiel, daher ist das -= wichtiger denn je: Ein zerstörtes ScoreBoard, das sich nie abgemeldet hat, würde weiterhin aufgerufen, und sein Code würde bei seinem zerstörten Text fehlschlagen. OnEnable und OnDisable treten paarweise auf, daher bekommt jedes += sein -=.
Aufgabe
EinfachDie Basis braucht Leben, und ein Gegner, der sie erreicht, muss sie kosten.
- Füge in
EnemyDataein öffentliches intdamagehinzu: die Anzahl Leben, die diese Art der Basis abzieht. - Deklariere in
Enemyein öffentliches statisches EreignisReachedBase, das den Gegner übergibt (Action<Enemy>). Wenn der Gegner den letzten Wegpunkt erreicht, löse das Ereignis mit sich selbst aus und zerstöre den Gegner, statt ihn dort anzuhalten. - Füge in
GameManagerein serialisiertes intstartLives(20) und ein privates intliveshinzu, das mit diesem Wert beginnt. AbonniereEnemy.ReachedBaseinOnEnableund hebe das Abonnement inOnDisableauf. Jeder Gegner, der durchkommt, zieht den Wertdamageseines Assets von den Leben ab. - Zeige die Leben in einem serialisierten TMP_Text
livesTextalsLives: 20an – zu Beginn und nach jeder Änderung.
Das Game-Objekt hat den GameManager, im Inspector ist LivesText zugewiesen, und beide Assets ziehen jeweils 1 Leben ab. Drücke Play, warte, bis beide Gegner die Basis erreichen, und klicke dann auf Check.
Probier es selbst
using UnityEngine;
public class Enemy : MonoBehaviour
{
public EnemyData data;
public Transform[] waypoints;
private int next = 1;
private int health;
void Awake()
{
health = data.maxHealth;
}
void Update()
{
if (next >= waypoints.Length)
{
return;
}
Vector3 target = waypoints[next].position;
transform.position = Vector3.MoveTowards(transform.position, target, data.speed * Time.deltaTime);
if (transform.position == target)
{
next++;
}
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.