Menu
CoddyTech

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 -=.

challenge icon

Aufgabe

Einfach

Die Basis braucht Leben, und ein Gegner, der sie erreicht, muss sie kosten.

  1. Füge in EnemyData ein öffentliches int damage hinzu: die Anzahl Leben, die diese Art der Basis abzieht.
  2. Deklariere in Enemy ein öffentliches statisches Ereignis ReachedBase, 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.
  3. Füge in GameManager ein serialisiertes int startLives (20) und ein privates int lives hinzu, das mit diesem Wert beginnt. Abonniere Enemy.ReachedBase in OnEnable und hebe das Abonnement in OnDisable auf. Jeder Gegner, der durchkommt, zieht den Wert damage seines Assets von den Leben ab.
  4. Zeige die Leben in einem serialisierten TMP_Text livesText als Lives: 20 an – 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++;
        }
    }
}
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 Unity-Spiel: Tower Defense