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.
Défi
MoyenExécute les états prêts du joueur à l’aide d’une machine.
- Dans
StateMachine.cs, écrispublic class StateMachineavecpublic IState Current { get; private set; }et une méthodeTick()qui la met à jour. ChangeState(IState next)ignore l’état actuel ; sinon, appelle Exit, définitCurrent, puis appelle Enter.Player: Start créemachine,walk,sneaket 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
1Des composants, pas des hiérarchies
De petits composantsUn script de base pour les ennemisComposants abstraitsDes composants qui fonctionnent ensembleRécapitulatif : tourelle modulaireRécapitulatif : canon double4Données sérialisées
Classes sérialisablesListes dans l’InspecteurÉnumérations dans l’InspecteurRécapitulatif : table de butinRécapitulatif : tirer le butin7Machines à états
Les états sous forme de classesL’état d’alerteUne machine à étatsTransitionsL’intelligence des ennemisLe chevalier attaqueRécapitulatif : états des portes2Les interfaces dans Unity
IDamageableInterfaces et TryGetComponentGetComponentsRécapitulatif : touche d’interactionLe plus proche à portée5ScriptableObjects
Ressources de donnéesStatistiques des armesParamètres partagésSauver le ventLes vagues comme donnéesRécapitulatif : base de données des objetsRécapitulatif : acheter dans la boutique3Événements
Les événements C# dans UnityS’abonner dans OnEnableChamps UnityEventLes événements pilotent l’interfaceRécapitulatif : fenêtre de succèsRécapitulatif : minuteur de la fenêtreEntraînez-vous par vous-même : Playground Unity