Menu
CoddyTech

Une machine à états

Fait partie de la section Architecture de jeu dans Unity du Journey Unity de Coddy. Leçon 37 sur 64.

La méthode SetState de la balise serait la même pour chaque objet ayant des états : une tourelle, un ennemi, une porte. Ce code peut être placé dans une classe à part, une machine à états, qui conserve l’état actuel et le modifie. Chaque objet crée une machine et l’appelle, au lieu de répéter le code :

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

Le premier appel à ChangeState n’a aucun état à quitter : Current est null, et ?. ignore l’appel à Exit. La section 1 signalait que ?. ne détecte pas le faux null de Unity ; cela concerne les objets Unity détruits, et les états sont de simples objets C#, donc ?. est sûr ici. Current a un private set, donc aucun script ne peut remplacer l’état sans passer par ChangeState et ses appels à Exit et Enter.

L’ordre à l’intérieur de ChangeState est important dès que deux états agissent sur la même chose. Exit annule les modifications de l’ancien état, puis Enter configure le nouveau, de sorte que le nouvel état a le dernier mot. Si le Enter d’un DarkState éteignait la lampe et s’exécutait avant le Exit de BlinkState, ce Exit rallumerait la lampe dans l’état sombre. StateMachine est également une classe ordinaire : la balise, une tourelle et un ennemi créent chacun la leur avec new et appellent son Tick depuis leur Update.

challenge icon

Défi

Moyen

Exécute les états prêts du joueur à l’aide d’une machine.

  1. Dans StateMachine.cs, écris public class StateMachine avec public IState Current { get; private set; } et une méthode Tick() qui la met à jour.
  2. ChangeState(IState next) ignore l’état actuel ; sinon, appelle Exit, définit Current, puis appelle Enter.
  3. Player : Start crée machine, walk, sneak et marche ; Update passe en mode furtif tant que la barre d’espace est maintenue, sinon marche, puis appelle Tick.

Appuie sur « Jouer » et maintiens la barre d’espace : Sneak: enter. Puis clique sur « Vérifier ».

Essayez vous-même

// StateMachine : Current, ChangeState et Tick

Toutes les leçons de Architecture de jeu dans Unity

Entraînez-vous par vous-même : Playground Unity