Menu
CoddyTech

Uma Máquina de Estados

Parte da seção Arquitetura de jogos no Unity do Journey de Unity da Coddy. Lição 29 de 50.

O método SetState do Beacon seria igual em todo objeto com estados: uma torre, um inimigo, uma porta. Esse código pode ficar em uma classe própria, uma máquina de estados, que mantém o estado atual e o altera. Cada objeto cria uma máquina e a chama, em vez de repetir o código:

public class StateMachine
{
    public IState Current { get; private set; }

    public void ChangeState(IState next)
    {
        Current?.Exit();
        Current = next;
        Current.Enter();
    }

    public void Tick()
    {
        Current?.Tick();
    }
}

public class Beacon : MonoBehaviour
{
    public Renderer lamp;
    private StateMachine machine = new StateMachine();
    private IState blink;
    private IState steady;

    void Start()
    {
        blink = new BlinkState(lamp);
        steady = new SteadyState();
        machine.ChangeState(steady);
    }

    void Update()
    {
        if (Keyboard.current.spaceKey.wasPressedThisFrame) machine.ChangeState(machine.Current == steady ? blink : steady);
        machine.Tick();
    }
}

O primeiro ChangeState não tem estado do qual sair: Current é null, e ?. ignora a chamada a Exit. A seção 1 alertou que ?. não detecta o null falso do Unity; isso se refere a objetos do Unity destruídos, e os estados são objetos C# comuns, então ?. é seguro aqui. Current tem um private set, então nenhum script pode trocar o estado sem passar por ChangeState e seus Exit e Enter.

A ordem dentro de ChangeState importa sempre que dois estados mexem na mesma coisa. Exit desfaz o que o estado antigo alterou, depois Enter configura o novo, então o novo estado tem a palavra final. Se o Enter de DarkState apagasse a lâmpada e fosse executado antes do Exit de BlinkState, esse Exit acenderia a lâmpada novamente no estado escuro. StateMachine também é uma classe comum: o beacon, uma torre e um inimigo criam cada um a sua com new e chamam seu Tick dentro de seu Update.

challenge icon

Desafio

Médio

Segure Espaço para andar furtivamente. WalkState e SneakState estão prontos em PlayerStates.cs: Enter e Exit registram o que acontece (Walk: enter, Sneak: exit...), e Tick chama o Move() do jogador. Escreva a máquina que os executa.

  • Em StateMachine.cs, escreva uma classe simples StateMachine com uma propriedade pública Current que só a máquina pode definir, um método ChangeState(IState next) que executa Exit do estado antigo e, em seguida, Enter do novo estado, e um método Tick() que executa Tick do estado atual.
  • O jogador solicita seu estado a cada quadro, então ChangeState não faz nada se o estado já for o atual: nem Exit nem Enter.
  • Em Player.cs, adicione um campo StateMachine chamado machine. Em Start, crie a máquina e os dois estados (cada um recebe o jogador) e comece andando. Em Update, mude para andar furtivamente enquanto Espaço estiver pressionada e para andar caso contrário; depois, atualize a máquina.

Pressione Play, caminhe, segure Espaço e continue caminhando, depois Check.

Experimente você mesmo

// StateMachine: Current, ChangeState e Tick
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 Arquitetura de jogos no Unity