Mach es zu deinem
Lektion 18 von 18 im Kurs Unity-Spiel: Tower Defense von Coddy.
Das Spiel braucht ein Ende. Verloren ist es, wenn die Leben auf 0 sinken, und gewonnen, wenn alle Wellen gestartet wurden und kein Gegner mehr auf dem Spielfeld ist. Der Spawner weiß, wann die letzte Welle unterwegs ist, und Enemy.All weiß, wie viele Gegner noch übrig sind. Daher wartet der Spawner, bis das Spielfeld leer ist, und löst dann ein Ereignis aus, auf das der GameManager reagiert. Eine Coroutine wartet mit WaitUntil auf eine Bedingung; dabei wird ein Lambda einmal pro Frame geprüft. Ein Rätselraum, der seinen Ausgang öffnet, sobald alle Schalter eingeschaltet sind:
yield return new WaitUntil(() => switchesOn == switches.Length);
exit.SetActive(true);Bei beiden Spielenden wird das EndPanel mit einer Nachricht angezeigt und das Spiel mit Time.timeScale = 0 angehalten. Die Anzahl der Leben sinkt nie unter 0: Ein Tank, der 2 Leben abzieht, wenn nur noch 1 übrig ist, würde eine Prüfung auf genau 0 überspringen. Deshalb sorgt Mathf.Max dafür, dass die Anzahl bei 0 oder höher bleibt.
Mit „Erneut spielen“ wird die Szene erneut geladen. Time.timeScale gehört nicht zur Szene und behält seinen Wert beim Laden bei. Ein bei 0 angehaltenes Spiel würde also wieder eingefroren starten: Setze den Wert vor dem Laden wieder auf 1.
Gestalte das Spiel anschließend nach deinen Vorstellungen. Alles, womit es ausbalanciert wird, findest du im Inspector:
- GameManagers des Spiels:
startMoney(150) undstartLives(20). - Die
wavesdes Spawners: acht Zeilen mit Gegnern, Anzahl und Abstand sowietimeBetweenWaves(8). - Die EnemyData-Assets: Geschwindigkeit, Gesundheit, Belohnung und die Anzahl der Leben, die jeder Gegnertyp abzieht. Der Boss hat 450 Gesundheit und zieht 10 Leben ab.
- Die TowerData-Assets: Kosten, Schaden, Reichweite, Feuerrate, die Upgrade-Werte, der Flächenschaden der Kanone und die Verlangsamung durch den Frostturm.
Mit einer gemischten Verteidigung in den Kurven des Weges, die mit steigendem Geld aufgerüstet wird, lassen sich die Standardwerte bewältigen; ein paar Türme desselben Typs reichen nicht aus. Ändere jeweils einen Wert und spiele, um herauszufinden, was er bewirkt.
Aufgabe
Schwer- Füge in
WaveSpawnerpublic event Action AllWavesClearedhinzu. Warte, nachdem die letzte Welle losgeschickt wurde, bisEnemy.Allleer ist, und löse dann das Ereignis aus. - Füge in
GameManagerdie serialisierten FelderendPanel(ein GameObject) undendText(ein TMP_Text) hinzu. Die Anzahl der Leben darf niemals unter 0 sinken, und wenn sie 0 erreicht, endet das Spiel mitGame Over. Wenn alle Wellen geschafft sind und noch Leben übrig sind, endet es mitYou Win!. Beim Spielende wird das Panel mit der Nachricht angezeigt undTime.timeScaleauf 0 gesetzt. - Schreibe
public void PlayAgain(), das der Button des Panels aufruft: Die Zeit wird wieder normal eingestellt und die aktive Szene erneut geladen.
Drücke Play und verteidige die Basis in allen acht Wellen, dann Check. Passe danach das Spiel im Inspector an und spiele es auf deine Weise.
Probier es selbst
using UnityEngine;
using TMPro;
public class GameManager : MonoBehaviour
{
[SerializeField] private int startMoney = 100;
[SerializeField] private int startLives = 20;
[SerializeField] private WaveSpawner spawner;
[SerializeField] private TMP_Text moneyText;
[SerializeField] private TMP_Text livesText;
[SerializeField] private TMP_Text waveText;
private int money;
private int lives;
void OnEnable()
{
Enemy.ReachedBase += OnReachedBase;
Enemy.Killed += OnKilled;
spawner.WaveStarted += ShowWave;
}
void OnDisable()
{
Enemy.ReachedBase -= OnReachedBase;
Enemy.Killed -= OnKilled;
spawner.WaveStarted -= ShowWave;
}
void Start()
{
money = startMoney;
lives = startLives;
ShowMoney();
ShowLives();
}
public bool TrySpend(int amount)
{
if (amount > money)
{
return false;
}
money -= amount;
ShowMoney();
return true;
}
public void Earn(int amount)
{
money += amount;
ShowMoney();
}
void OnKilled(Enemy enemy)
{
Earn(enemy.data.reward);
}
void OnReachedBase(Enemy enemy)
{
lives -= enemy.data.damage;
ShowLives();
}
void ShowMoney()
{
moneyText.text = "Money: " + money;
}
void ShowLives()
{
livesText.text = "Lives: " + lives;
}
void ShowWave(int wave, int total)
{
waveText.text = "Wave " + wave + "/" + total;
}
}
Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.