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.
Desafio
FácilCrie a corrida de toques de 5 segundos.
- Em
SetState, mostre apenas o painel do novo estado. Ao entrar em Playing, definataps = 0,timeLeft = roundTimeeTaps: 0; ao entrar em GameOver, mostreTaps: 3emresultText. - Em
Update(), useswitch (state): a tecla Espaço leva de Ready para Playing e de GameOver para Ready; em Playing, conte cada pressionamento de Espaço emtapsetapsTextaté 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
1Texto na tela
Canvas e textoExiba a pontuaçãoFormate númerosUm cronômetro regressivoRevisão: velocímetro2Botões e telas
Botões e onClickLambdasConectando no InspectorPainéis ligados e desligadosBarras de vidaRevisão: Loja de melhorias5Salvando com PlayerPrefs
Salvar um númeroCarregar com um valor padrãoRecordeSalvar configuraçõesRevisão: Moedas no banco3O Gerenciador do Jogo
Um Script Controla o JogoO SingletonEstados do JogoAlternando o EstadoRevisão: Gerenciador de RodadasPratique por conta própria: Playground de Unity