Menu
CoddyTech

Uma máquina de estados

Parte da seção Arquitetura de Jogos no Unity do Journey de Unity da Coddy. Lição 37 de 64.

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();
    }
}

A primeira chamada a ChangeState não tem estado para abandonar: Current é null, e ?. ignora a chamada a Exit. A Seção 1 alertou que ?. não detecta o null falso do Unity; isso se aplica a objetos 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 métodos 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 um DarkState apagasse a lâmpada e fosse executado antes do Exit de BlinkState, esse Exit acenderia a lâmpada de novo no estado escuro. A StateMachine também é uma classe comum: o beacon, uma torre e um inimigo criam cada um a sua com new e chamam seu Tick no Update.

challenge icon

Desafio

Médio

Execute os estados do jogador com uma máquina.

  1. Em StateMachine.cs, escreva public class StateMachine com public IState Current { get; private set; } e um Tick() que atualiza o estado.
  2. ChangeState(IState next) ignora o estado atual; caso contrário, executa Exit, define Current e executa Enter.
  3. Player: Start cria machine, walk e sneak e inicia o estado de caminhada; Update inicia o estado de furtividade enquanto Space estiver pressionado; caso contrário, inicia o estado de caminhada e, em seguida, atualiza o estado.

Pressione “Jogar” e mantenha Space pressionada: Sneak: enter. Em seguida, pressione “Verificar”.

Experimente você mesmo

// StateMachine: Current, ChangeState e Tick

Todas as lições de Arquitetura de Jogos no Unity

Pratique por conta própria: Playground de Unity