Menu
CoddyTech

打造属于你的作品

Coddy Unity 塔防游戏 课程的第 25 课,共 25 课。

游戏需要一个结局。生命值降到 0 时游戏失败,所有波次都已发出且没有敌人剩下时游戏胜利。生成器使用 WaitUntil 等待场地清空。它每帧检查一次 lambda,然后触发一个事件:

yield return new WaitUntil(() => switchesOn == switches.Length);

无论哪种结局,都会显示 EndPanel 并通过 Time.timeScale = 0 停止游戏。如果 Tank 在只剩 1 点生命值时受到 2 点伤害,就会跳过对生命值是否恰好为 0 的检查,因此 Mathf.Max 会将生命值限制在 0 或更高。场景加载后,Time.timeScale 会保留原来的值,所以“再玩一次”会先将它重置为 1。

然后打造属于你自己的游戏。这里的 startMoney(150)、startLives(20)和 timeBetweenWaves(8)会使用你在代码中设置的值,因为这位玩家的 Inspector 只能读取:在声明这些变量的位置修改它们,然后按“运行”。在路径的弯道处布置混合防御,并随着资金增加进行升级,就能打败默认游戏。

challenge icon

挑战

困难

结束游戏,然后在代码中调整它。

  1. WaveSpawner:添加 public event Action AllWavesCleared;,最后一波结束后,在 Enemy.All.Count == 0 时触发(WaitUntil)。
  2. GameManager:确保生命值不低于 0。End(message) 会显示序列化的 endPanel 和 endText,并设置 Time.timeScale = 0:生命值为 0 时显示 Game Over,所有波次清除后显示 You Win!。
  3. public void PlayAgain():设置 Time.timeScale = 1,然后重新加载场景。

点击运行,守住基地,抵挡全部 8 波敌人。然后点击检查。

亲手试试

using UnityEngine;
using TMPro;

public class GameManager : MonoBehaviour
{
    [SerializeField] private int startMoney = 150;
    [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;
    }
}
quiz icon自我测试

这节课包含一个小测验。开始学习即可作答,并记录你的进度。

Unity 塔防游戏中的所有课

自己练习: Unity 在线编辑器