Menu
CoddyTech

Personalize

Lição 18 de 18 do curso Jogo de Unity: Defesa de Torres da Coddy.

O jogo precisa de um final. Você perde quando as vidas chegam a 0 e vence quando todas as ondas tiverem sido enviadas e não houver mais nenhum inimigo no tabuleiro. O spawner sabe quando a última onda foi enviada, e Enemy.All sabe quantos inimigos restam, então o spawner espera o tabuleiro ficar vazio e, em seguida, dispara um evento ao qual o GameManager está inscrito. Uma coroutine espera por uma condição usando WaitUntil, que verifica uma lambda uma vez por frame. Uma sala de quebra-cabeça que abre sua saída quando todos os interruptores estão ligados:

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

Qualquer um dos finais mostra o EndPanel com uma mensagem e para o jogo com Time.timeScale = 0. As vidas nunca ficam abaixo de 0: um Tank que recebe 2 de dano quando resta 1 vida passaria direto por uma verificação de exatamente 0, então Mathf.Max mantém o valor em 0 ou mais.

Jogar Novamente carrega a cena outra vez. Time.timeScale não faz parte da cena e mantém seu valor após o carregamento, então um jogo parado em 0 começaria congelado outra vez: defina-o como 1 antes de carregar.

Agora, deixe o jogo com a sua cara. Tudo o que afeta o equilíbrio está no Inspector:

  • GameManager do jogo: startMoney (150) e startLives (20).
  • As waves do Spawner, oito linhas com o tipo de inimigo, a quantidade e o espaçamento, e timeBetweenWaves (8).
  • Os assets EnemyData: velocidade, vida, recompensa e quantas vidas cada tipo consome. O Boss tem 450 de vida e consome 10.
  • Os assets TowerData: custo, dano, alcance, cadência de tiro, os valores das melhorias, o dano em área do Cannon e a lentidão da torre Frost.

É possível vencer usando os valores padrão com uma defesa mista nas curvas do caminho, melhorada conforme o dinheiro chega; algumas torres de um só tipo não serão suficientes. Mude um número de cada vez e jogue para perceber o efeito.

challenge icon

Desafio

Difícil
  1. Em WaveSpawner, adicione public event Action AllWavesCleared. Depois que a última onda for enviada, aguarde até que Enemy.All esteja vazio e, em seguida, dispare o evento.
  2. Em GameManager, adicione os campos serializados endPanel (um GameObject) e endText (um TMP_Text). As vidas nunca ficam abaixo de 0 e, quando chegam a 0, o jogo termina com Game Over. Quando todas as ondas forem concluídas e ainda houver vidas, o jogo termina com You Win!. Ao terminar, exiba o painel com a mensagem e defina Time.timeScale como 0.
  3. Escreva public void PlayAgain(), que será chamado pelo botão do painel: restaure o tempo ao normal e carregue novamente a cena ativa.

Pressione Play e defenda a base durante as oito ondas; depois, clique em Check. Em seguida, ajuste o jogo no Inspector e jogue do seu jeito.

Experimente você mesmo

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;
    }
}
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Jogo de Unity: Defesa de Torres