Les états sous forme de classes
Fait partie de la section Architecture de jeu dans Unity du Journey Unity de Coddy. Leçon 28 sur 50.
Le switch sur une énumération de la section 3 concentre le travail de chaque état dans un seul Update. Cette approche ne passe pas à l’échelle lorsque les états ont leurs propres données : un minuteur utilisé par un seul état finit par devenir un champ de MonoBehaviour, à côté des champs de tous les autres états, et chaque case doit penser à réinitialiser ce qu’elle utilise. Le patron de conception State 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 barre d’espace permet de basculer entre les deux :
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#, pas des MonoBehaviours. Tu les crées avec new et tu leur transmets ce dont elles ont besoin par le constructeur, ici le Renderer de la lampe, car ce ne sont pas des composants et elles 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 remet à 0 chaque fois que la balise commence à clignoter. Exit effectue le nettoyage à la fin de l’état : la barre d’espace peut être pressée alors que la lampe est éteinte, et Exit la rallume, afin que SteadyState ne démarre jamais avec une lampe éteinte. SetState exécute Exit de l’ancien état, puis Enter du nouvel état. Un troisième état, comme une pulsation lente, correspond à une classe supplémentaire, et le Update de Beacon ne change pas.
Défi
MoyenUne tourelle sentinelle garde la cour. Les flèches déplacent le Player (prêt). Donne deux états à la tourelle, écrits sous forme de classes :
- Dans
IState.cs, déclarepublic interface IStateavecvoid Enter(),void Tick()etvoid Exit(). - Dans
TurretStates.cs, écris deux classes simples qui l'implémentent.ScanStatereçoit la tête de la tourelle dans son constructeur. Elle balaie d'un côté à l'autre : l'angle y local de la tête se déplace à 90 degrés par seconde entre-45et45, en commençant à 0 et en s'orientant vers le haut à chaque début de balayage. Son Enter colore également la tête enColor.green. AlertStatereçoit la tête et le joueur. Son Enter colore la tête enColor.redet afficheIntruder!dans le journal ; son Tick tourne la tête pour qu'elle regarde le joueur uniquement autour de l'axe y, sans inclinaison ; son Exit afficheAll cleardans le journal.- Dans
Turret.cs, crée les deux états dans Start et commence le balayage. À chaque image, passe à l'état d'alerte lorsque le joueur est plus près de la tourelle querange(4), et reviens au balayage quand ce n'est pas le cas, puis exécute le Tick de l'état actuel. Un changement exécute le Exit de l'ancien état, puis le Enter du nouvel état.
Appuie sur Play, approche-toi de la tourelle puis éloigne-toi, et enfin clique sur Check.
Essayez vous-même
using UnityEngine;
// ScanState et AlertState
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Architecture de jeu dans Unity
1Des composants, pas des hiérarchies
Des composants simplesUn script de base pour les ennemisDes composants abstraitsDes composants qui fonctionnent ensembleRécapitulatif : tourelle modulaire4Données sérialisées
Classes sérialisablesListes dans l’inspecteurÉnumérations dans l’inspecteurRécapitulatif : table de butin7Machines à états
Les états sous forme de classesUne machine à étatsTransitionsLes cerveaux des ennemisRécapitulatif : états d’une porte10Projet : Survivant de l’arène
Le hérosTypes d’ennemis2Interfaces dans Unity
IDamageableInterfaces et TryGetComponentGetComponentsRécapitulatif : touche d’interaction5ScriptableObjects
Assets de donnéesStatistiques des armesParamètres partagésLes vagues sous forme de donnéesRécapitulatif : base de données d’objets