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.
Desafio
MédioSegure 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 simplesStateMachinecom uma propriedade públicaCurrentque só a máquina pode definir, um métodoChangeState(IState next)que executa Exit do estado antigo e, em seguida, Enter do novo estado, e um métodoTick()que executa Tick do estado atual. - O jogador solicita seu estado a cada quadro, então
ChangeStatenão faz nada se o estado já for o atual: nem Exit nem Enter. - Em
Player.cs, adicione um campoStateMachinechamadomachine. 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
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