Les états sous forme de classes
Fait partie de la section Architecture de jeu dans Unity du Journey Unity de Coddy. Leçon 35 sur 64.
Le commutateur sur une énumération de la section 3 regroupe le travail de chaque état dans un seul Update. Cette approche ne passe plus à l’échelle dès que les états possèdent leurs propres données : un minuteur utilisé par un seul état se retrouve comme champ du MonoBehaviour, à côté des champs de tous les autres états, et chaque cas doit penser à réinitialiser ce qu’il utilise. Le patron de conception d’état de C# donne à chaque état sa propre classe, et chaque classe implémente une interface. Cette balise routière clignote ou reste allumée, et la touche Espace permet de passer de l’un à l’autre :
public interface IState
{
void Enter();
void Tick();
void Exit();
}
public class BlinkState : IState
{
private Renderer lamp;
private float timer;
public BlinkState(Renderer lamp)
{
this.lamp = lamp;
}
public void Enter() { timer = 0f; }
public void Tick()
{
timer += Time.deltaTime;
if (timer >= 0.5f)
{
timer = 0f;
lamp.enabled = !lamp.enabled;
}
}
public void Exit() { lamp.enabled = true; }
}
public class SteadyState : IState
{
public void Enter() { }
public void Tick() { }
public void Exit() { }
}
public class Beacon : MonoBehaviour
{
public Renderer lamp;
private IState blink;
private IState steady;
private IState current;
void Start()
{
blink = new BlinkState(lamp);
steady = new SteadyState();
SetState(steady);
}
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame) SetState(current == steady ? blink : steady);
current.Tick();
}
void SetState(IState next)
{
if (current != null) current.Exit();
current = next;
current.Enter();
}
}Les états sont de simples classes C#, et non des MonoBehaviours. Tu les crées avec new et tu leur transmets ce dont ils ont besoin via le constructeur, ici le Renderer de la lampe, car ce ne sont pas des composants et ils ne peuvent ni appeler GetComponent ni afficher de champs dans l’Inspector. Unity n’appelle pas non plus leurs méthodes : Beacon est le MonoBehaviour, donc son Update appelle current.Tick() à chaque image.
Le timer appartient uniquement à BlinkState, et son Enter le réinitialise à 0 à chaque fois que la balise se met à clignoter. Exit effectue le nettoyage à la fin de l’état : la barre d’espace peut être actionnée lorsque la lampe est éteinte, et Exit la rallume, si bien que SteadyState ne commence jamais avec une lampe éteinte. SetState exécute Exit de l’ancien état, puis Enter du nouvel état. Un troisième état, par exemple une impulsion lente, correspond à une classe supplémentaire, et le Update de Beacon reste inchangé.
Défi
MoyenÉcris l’état de balayage de la tourelle.
- Dans
IState.cs, déclarepublic interface IStateavecvoid Enter();,void Tick();etvoid Exit();. - Dans
TurretStates.cs, écrisScanState : IState, en lui passant la tête. Entrée : angle à 0, tête enColor.green. Mise à jour : fais pivoter la tête autour de son axe y local entre-45et45, à90degrés par seconde. Turret: fais-en entrer une dans Start et mets-la à jour dans Update.
Appuie sur « Jouer » : la tête verte balaie la zone. Puis appuie sur « Vérifier ».
Essayez vous-même
using UnityEngine;
// ScanState
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