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.
Desafío
IntermedioEjecuta los estados de preparación del jugador con una máquina.
- En
StateMachine.cs, escribepublic class StateMachineconpublic IState Current { get; private set; }y unTick()que lo actualice. ChangeState(IState next)ignora el estado actual; si no, ejecuta Exit, asignaCurrenty ejecuta Enter.Player: Start creamachine,walk,sneaky 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
1Componentes, no jerarquías
Componentes pequeñosUn script base para enemigosComponentes abstractosComponentes que trabajan juntosRepaso: torreta modularRepaso: cañón doble4Datos serializados
Clases serializablesListas en el InspectorEnumeraciones en el InspectorRepaso: tabla de botínRepaso: sortear el botín7Máquinas de estados
Estados como clasesEl estado de alertaUna máquina de estadosTransicionesCerebros enemigosEl caballero atacaRepaso: estados de puertas2Interfaces en Unity
IDamageableInterfaces y TryGetComponentGetComponentsRepaso: Tecla de interacciónRepaso: El más cercano al alcance5ScriptableObjects
Activos de datosEstadísticas de armasConfiguración compartidaGuardar el vientoOleadas como datosRepaso: base de datos de objetosRepaso: comprar en la tienda3Eventos
Eventos de C# en UnitySuscribirse en OnEnableCampos UnityEventLos eventos controlan la interfazRepaso: ventana emergente de logrosRepaso: temporizador de la ventana emergentePractica por tu cuenta: Playground de Unity