Estados como Classes
Parte da seção Arquitetura de jogos no Unity do Journey de Unity da Coddy. Lição 28 de 50.
O switch de enum da Seção 3 mantém o trabalho de cada estado em um único Update. Isso deixa de escalar quando os estados passam a ter dados próprios: um temporizador usado por apenas um estado acaba como um campo do MonoBehaviour, ao lado dos campos de todos os outros estados, e cada case precisa se lembrar de redefinir o que usa. O padrão de estado de C# dá a cada estado sua própria classe, e cada classe implementa uma interface. Este sinalizador rodoviário pisca ou permanece aceso, e Space alterna entre os dois:
public interface IState
{
void Enter();
void Tick();
void Exit();
}
public class BlinkState : IState
{
private Renderer lamp;
private float timer;
public BlinkState(Renderer lamp)
{
this.lamp = lamp;
}
public void Enter() { timer = 0f; }
public void Tick()
{
timer += Time.deltaTime;
if (timer >= 0.5f)
{
timer = 0f;
lamp.enabled = !lamp.enabled;
}
}
public void Exit() { lamp.enabled = true; }
}
public class SteadyState : IState
{
public void Enter() { }
public void Tick() { }
public void Exit() { }
}
public class Beacon : MonoBehaviour
{
public Renderer lamp;
private IState blink;
private IState steady;
private IState current;
void Start()
{
blink = new BlinkState(lamp);
steady = new SteadyState();
SetState(steady);
}
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame) SetState(current == steady ? blink : steady);
current.Tick();
}
void SetState(IState next)
{
if (current != null) current.Exit();
current = next;
current.Enter();
}
}Os estados são classes simples de C#, não MonoBehaviours. Você os cria com new e passa a eles o que precisam pelo construtor — aqui, o Renderer da lâmpada —, porque não são componentes e não podem chamar GetComponent nem exibir campos no Inspector. A Unity também nunca chama seus métodos: Beacon é o MonoBehaviour, então seu Update chama current.Tick() a cada frame.
O timer pertence somente a BlinkState, e seu Enter o define como 0 sempre que o sinalizador começa a piscar. Exit faz a limpeza quando o estado termina: Space pode ser pressionada enquanto a lâmpada está apagada, e Exit a acende novamente, para que SteadyState nunca comece com a lâmpada apagada. SetState executa Exit do estado antigo e, em seguida, Enter do novo estado. Um terceiro estado, como um pulso lento, é mais uma classe, e o Update de Beacon não muda.
Desafio
MédioUma torre sentinela protege o pátio. As setas movimentam o Player (pronto). Dê dois estados à torre, escritos como classes:
- Em
IState.cs, declarepublic interface IStatecomvoid Enter(),void Tick()evoid Exit(). - Em
TurretStates.cs, escreva duas classes simples que implementem essa interface.ScanStaterecebe a cabeça da torre no construtor. Ela varre de um lado para o outro: o ângulo y local da cabeça se move a 90 graus por segundo entre-45e45, começando em 0 e virando para cima sempre que a varredura começa. Seu Enter também colore a cabeça comColor.green. AlertStaterecebe a cabeça e o jogador. Seu Enter colore a cabeça comColor.rede registraIntruder!; seu Tick vira a cabeça para encarar o jogador somente em torno do eixo y, sem inclinação; seu Exit registraAll clear.- Em
Turret.cs, crie os dois estados em Start e comece a varredura. A cada quadro, mude para o estado de alerta quando o jogador estiver mais perto da torre do querange(4) e volte à varredura quando não estiver; em seguida, execute o Tick do estado atual. Uma mudança executa o Exit do estado antigo e, depois, o Enter do novo estado.
Pressione Play, aproxime-se da torre e depois se afaste; em seguida, pressione Check.
Experimente você mesmo
using UnityEngine;
// ScanState e AlertState
Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.
Todas as lições de Arquitetura de jogos no Unity
1Componentes, não hierarquias
Componentes pequenosUm script-base para inimigosComponentes abstratosComponentes trabalhando juntosRevisão: Torre modular4Dados Serializados
Classes SerializáveisListas no InspectorEnums no InspectorRevisão: Tabela de Loot7Máquinas de Estados
Estados como ClassesUma Máquina de EstadosTransiçõesInteligências dos InimigosRevisão: Estados da Porta10Projeto: Sobrevivente da Arena
O HeróiTipos de Inimigos5ScriptableObjects
Assets de dadosAtributos das armasConfigurações compartilhadasOndas como dadosRevisão: banco de dados de itens