Menu
CoddyTech

Una máquina de estados

Parte de la sección Arquitectura de juegos en Unity del Journey de Unity de Coddy. Lección 37 de 64.

El método SetState del faro sería igual en todos los objetos con estados: una torreta, un enemigo, una puerta. Ese código puede estar en una clase propia, una máquina de estados, que mantiene el estado actual y lo cambia. Cada objeto crea una máquina y la llama, en lugar de repetir el 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();
    }
}

La primera llamada a ChangeState no tiene ningún estado del que salir: Current es null, y ?. omite la llamada a Exit. En la sección 1 se advirtió que ?. no detecta el valor null falso de Unity; eso se refiere a los objetos de Unity destruidos, y los estados son objetos C# normales, así que ?. es seguro aquí. Current tiene un private set, así que ningún script puede cambiar el estado sin pasar por ChangeState y sus llamadas a Exit y Enter.

El orden dentro de ChangeState importa siempre que dos estados afecten al mismo elemento. Exit revierte lo que cambió el estado anterior, y luego Enter configura el nuevo, así que el nuevo estado tiene la última palabra. Si el método Enter de DarkState apagara la lámpara y se ejecutara antes que Exit de BlinkState, ese Exit volvería a encender la lámpara en el estado oscuro. StateMachine también es una clase normal: el faro, una torreta y un enemigo crean cada uno su propia instancia con new y llaman a su Tick desde su Update.

challenge icon

Desafío

Intermedio

Ejecuta los estados de preparación del jugador con una máquina.

  1. En StateMachine.cs, escribe public class StateMachine con public IState Current { get; private set; } y un Tick() que lo actualice.
  2. ChangeState(IState next) ignora el estado actual; si no, ejecuta Exit, asigna Current y ejecuta Enter.
  3. Player: Start crea machine, walk, sneak y camina; Update se escabulle mientras se mantiene presionada la barra espaciadora; si no, camina y después actualiza.

Presiona «Jugar» y mantén presionada la barra espaciadora: Sneak: enter. Después, «Comprobar».

Pruébalo tú mismo

// StateMachine: Current, ChangeState y Tick

Todas las lecciones de Arquitectura de juegos en Unity

Practica por tu cuenta: Playground de Unity