Menu
CoddyTech

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.

challenge icon

Défi

Moyen

Une 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éclare public interface IState avec void Enter(), void Tick() et void Exit().
  • Dans TurretStates.cs, écris deux classes simples qui l'implémentent. ScanState reç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 -45 et 45, en commençant à 0 et en s'orientant vers le haut à chaque début de balayage. Son Enter colore également la tête en Color.green.
  • AlertState reçoit la tête et le joueur. Son Enter colore la tête en Color.red et affiche Intruder! 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 affiche All clear dans 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 que range (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
quiz iconTestez-vous

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