Menu
CoddyTech

Alternando o Estado

Parte da seção Criando Jogos de Verdade do Journey de Unity da Coddy. Lição 15 de 60.

Cada estado de um jogo realiza um trabalho diferente a cada quadro. Um switch sobre o campo de estado coloca esse trabalho em um caso para cada estado, e cada quadro executa exatamente um caso. A mudança de estado passa por um único método, então a tela sempre corresponde ao estado. Esta luta contra o chefe tem uma introdução, a luta e uma tela de vitória:

public enum Phase { Intro, Fight, Won }

public class BossFight : MonoBehaviour
{
    public GameObject introPanel;
    public GameObject fightPanel;
    public GameObject winPanel;
    public int bossHp = 10;
    private Phase phase;
    private float timer = 3f;

    void Start()
    {
        Enter(Phase.Intro);
    }

    void Update()
    {
        switch (phase)
        {
            case Phase.Intro:
                timer -= Time.deltaTime;
                if (timer <= 0f) Enter(Phase.Fight);
                break;
            case Phase.Fight:
                if (bossHp <= 0) Enter(Phase.Won);
                break;
            case Phase.Won:
                break;
        }
    }

    void Enter(Phase next)
    {
        phase = next;
        introPanel.SetActive(next == Phase.Intro);
        fightPanel.SetActive(next == Phase.Fight);
        winPanel.SetActive(next == Phase.Won);
    }
}

Cada caso termina com break, porque C# se recusa a compilar um caso que continua executando o próximo. Quando o temporizador da introdução chega a zero, Enter(Phase.Fight) muda a fase, mas o caso Fight só é executado no quadro seguinte, porque este quadro já escolheu seu caso. Com blocos if separados, um após o outro, um quadro poderia iniciar a luta e executar o código da luta no mesmo quadro.

Enter é o único lugar que altera phase. next == Phase.Fight é true apenas para o painel da luta, então uma chamada exibe esse painel e oculta os outros dois. O trabalho que deve ocorrer ao entrar em um estado, como reiniciar um temporizador, também fica em Enter e é executado uma vez, em vez de a cada quadro.

challenge icon

Desafio

Fácil

Crie a corrida de toques de 5 segundos.

  1. Em SetState, mostre apenas o painel do novo estado. Ao entrar em Playing, defina taps = 0, timeLeft = roundTime e Taps: 0; ao entrar em GameOver, mostre Taps: 3 em resultText.
  2. Em Update(), use switch (state): a tecla Espaço leva de Ready para Playing e de GameOver para Ready; em Playing, conte cada pressionamento de Espaço em taps e tapsText até o tempo acabar.

Pressione “Jogar” e dispute duas corridas. Depois, pressione “Verificar”.

Experimente você mesmo

using UnityEngine;
using TMPro;

public enum GameState { Ready, Playing, GameOver }

public class GameManager : MonoBehaviour
{
    public GameObject readyPanel;
    public GameObject playPanel;
    public GameObject gameOverPanel;
    public TMP_Text tapsText;
    public TMP_Text resultText;
    public float roundTime = 5f;
    public GameState state;
    private int taps;
    private float timeLeft;

    void Start()
    {
        SetState(GameState.Ready);
    }

    void Update()
    {
        // use switch com base em state:
        // Ready: Space inicia uma rodada
        // Playing: Space registra um toque; quando o tempo acaba, o jogo termina
        // GameOver: Space volta para Ready
    }

    void SetState(GameState next)
    {
        state = next;
        // mostre apenas o painel do novo estado
        // uma nova rodada começa com 0 toques e roundTime segundos; ao final, resultText mostra o número de toques
    }
}

Todas as lições de Criando Jogos de Verdade

Pratique por conta própria: Playground de Unity