Transitions
Fait partie de la section Architecture de jeu dans Unity du Journey Unity de Coddy. Leçon 38 sur 64.
Qui décide quand l’état change ? Demander au propriétaire de s’en charger ramène toutes les règles dans un seul Update, comme le faisait le switch. La réponse habituelle est que chaque état connaît sa propre sortie : dans son Tick, il vérifie sa condition et demande à la machine de passer à l’état suivant. Cette bombe attend que le joueur s’approche, puis brûle sa mèche et se remet à attendre si le joueur s’enfuit :
public class Bomb : MonoBehaviour
{
public Transform player;
public StateMachine machine = new StateMachine();
public IState idle;
public IState fuse;
void Start()
{
idle = new IdleState(this);
fuse = new FuseState(this);
machine.ChangeState(idle);
}
void Update() { machine.Tick(); }
public bool PlayerNear()
{
return Vector3.Distance(transform.position, player.position) < 3f;
}
}
public class IdleState : IState
{
private Bomb bomb;
public IdleState(Bomb bomb) { this.bomb = bomb; }
public void Enter() { }
public void Exit() { }
public void Tick()
{
if (bomb.PlayerNear()) bomb.machine.ChangeState(bomb.fuse);
}
}
public class FuseState : IState
{
private Bomb bomb;
private float timer;
public FuseState(Bomb bomb) { this.bomb = bomb; }
public void Enter() { timer = 2f; }
public void Exit() { }
public void Tick()
{
if (!bomb.PlayerNear())
{
bomb.machine.ChangeState(bomb.idle);
return;
}
timer -= Time.deltaTime;
if (timer <= 0f)
{
Debug.Log("Boom!");
Object.Destroy(bomb.gameObject);
}
}
}Chaque état reçoit la bombe dans son constructeur et accède par son intermédiaire à la machine, au test du joueur et aux autres états. La bombe crée chaque état une seule fois, dans Start, de sorte qu’un état n’en crée jamais un autre avec new : deux états qui se créeraient mutuellement dans leurs constructeurs boucleraient jusqu’au dépassement de la pile. L’Update de la bombe ne fait que faire avancer la machine, et les règles se trouvent dans les états auxquels elles appartiennent : la mèche de 2 secondes ne concerne que FuseState.
ChangeState exécute Exit de FuseState et Enter de IdleState immédiatement, mais le reste du Tick de FuseState continuerait à s’exécuter après l’appel. Le return l’arrête ; sinon, la mèche brûlerait une frame de plus alors que l’état est déjà terminé. Destroy s’écrit Object.Destroy : un MonoBehaviour hérite de cette méthode de la classe Object de Unity, tandis qu’une classe ordinaire doit nommer la classe.
Défi
MoyenÉcris les transitions du piège à mouches dans chaque Tick de FlytrapStates.cs.
- Open : lorsque
trap.PlayerInReach(), appelletrap.machine.ChangeState(trap.snap);. - Snap : ajoute
Time.deltaTimeàtimer; à0.5, passe àtrap.chewsi le joueur est toujours à portée, sinon àtrap.open. - Chew : fais décroître
timerà partir de 3 ; à 0, passe àtrap.open.
Appuie sur « Jouer », marche dans le piège, puis esquive-le. Ensuite, appuie sur « Vérifier ».
Essayez vous-même
using UnityEngine;
public class OpenState : IState
{
private Flytrap trap;
public OpenState(Flytrap trap)
{
this.trap = trap;
}
public void Enter()
{
trap.Paint(new Color(0.3f, 0.8f, 0.2f));
}
public void Tick()
{
// Se refermer lorsque le joueur est à portée
}
public void Exit()
{
}
}
public class SnapState : IState
{
private Flytrap trap;
private float timer;
public SnapState(Flytrap trap)
{
this.trap = trap;
}
public void Enter()
{
timer = 0f;
trap.Paint(new Color(1f, 0.55f, 0.1f));
}
public void Tick()
{
// Après 0.5 seconde : mâcher si le joueur est toujours à portée, sinon se rouvrir
}
public void Exit()
{
}
}
public class ChewState : IState
{
private Flytrap trap;
private float timer;
public ChewState(Flytrap trap)
{
this.trap = trap;
}
public void Enter()
{
timer = 3f;
trap.Paint(new Color(0.5f, 0.05f, 0.1f));
Debug.Log("Chomp!");
}
public void Tick()
{
// Après 3 secondes : se rouvrir
}
public void Exit()
{
}
}
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 butin2Les 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