Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Apprendre État de Course | Comportement de l'Ennemi
Jeu de Combat dans Unity
course content

Contenu du cours

Jeu de Combat dans Unity

Jeu de Combat dans Unity

1. Système d'Animation Unity
2. Comportement du Joueur
3. Comportement de l'Ennemi
4. Améliorer le Jeu
5. Améliorer le Jeu Flappy Bird

book
État de Course

public abstract class State
{
    public bool isStateFinished;

    public abstract void StartState();
    public virtual void UpdateState()
    {
    }
    public abstract void EndState();
    public virtual void FinishState()
    {
        isStateFinished = true;
    }
}

Modifications et ajouts

Variable isStateFinished :

Variable booléenne indiquant si l’état a terminé son exécution.

Méthode FinishState :

Nouvelle méthode virtuelle qui définit isStateFinished à true. Le fait qu’elle soit virtuelle permet aux classes dérivées de la redéfinir si des actions supplémentaires sont nécessaires à la fin d’un état.

Raisons de ces modifications

Les modifications introduisent la variable isStateFinished pour suivre l’achèvement de l’état et la méthode FinishState pour standardiser le signalement de la fin d’un état, permettant ainsi aux classes dérivées d’ajouter une logique personnalisée lors de la complétion de l’état.

État de course

public class RunState : State
{
    Rigidbody2D rb;
    Animator animator;
    Transform player;
    float speed;
    Vector2 scale;
    Vector2 velocity;

    public RunState(Rigidbody2D rb, Animator animator, Transform p, float speed)
    {
        this.animator = animator;
        player = p;
        this.speed = speed;
        this.rb = rb;
        scale = rb.transform.localScale;
        velocity = new Vector2();
    }

    public override void StartState()
    {
        isStateFinished = false;
        animator.SetBool("run", true);
    }

    public override void UpdateState(float DeltaTime)
    {
        scale.x = rb.position.x > player.position.x ? -1 : 1;
        rb.transform.localScale = scale;

        velocity.x = scale.x * speed;
        rb.velocity = velocity;
    }

    public override void EndState()
    {
        animator.SetBool("run", false);
    }
}

Examinons la classe RunState, qui hérite de la classe State. Cette classe est responsable de la gestion du comportement de course de notre ennemi. Nous allons nous concentrer sur les ajouts et modifications apportés à cette classe.

Constructeur :

public RunState(Rigidbody2D rb, Animator animator, Transform p, float speed);

Ce constructeur initialise le RunState avec les composants nécessaires : un Rigidbody2D pour le déplacement, un Animator pour les animations, un Transform pour suivre le joueur, et une speed pour la vitesse de déplacement de l’ennemi ;

Méthode StartState :

public override void StartState(); Cette méthode définit isStateFinished sur false et déclenche l’animation de course en activant le paramètre booléen "run" dans l’animator à true.

Méthode UpdateState :

public override void UpdateState(float DeltaTime); Cette méthode met à jour la position et l’orientation de l’ennemi en fonction de la position du joueur ; Elle ajuste l’échelle de l’ennemi pour qu’il fasse face au joueur, calcule la vélocité en fonction de la vitesse, et applique cette vélocité au Rigidbody2D.

Méthode EndState :

public override void EndState() Cette méthode arrête l'animation de course en définissant le paramètre booléen "run" dans l'Animator à false.

Fonctionnement pour notre ennemi

  • Déplacement et animation : En utilisant Rigidbody2D et Animator, le RunState permet à l'ennemi de se déplacer de manière fluide avec des animations correspondantes. Ce comportement assure un réalisme visuel et physique ;

  • Suivi de la position du joueur : Le transform du player permet à l'ennemi de toujours se diriger vers le joueur, ce qui est essentiel pour les comportements de poursuite ou de fuite ;

  • Gestion de la direction : L'ajustement du scale.x en fonction de la position du joueur garantit que l'ennemi fait toujours face au joueur pendant la course, renforçant ainsi le réalisme ;

  • Mises à jour dynamiques de l'état : La méthode UpdateState est appelée à chaque frame pour ajuster en continu le mouvement et la direction de l'ennemi selon la position du joueur, rendant l'ennemi réactif et dynamique.

Initialisation de l'ennemi

private void Start()
{
    idle = new IdleState(animator);
    runState = new RunState(GetComponent<Rigidbody2D>(), animator, player, speed);
    stateManager = new StateManager(idle);

    FarAwayTransition = new Transition(() =>
    {
        return (ThresholdDistance < Vector2.Distance(transform.position, player.position));
    }, new StatePourcentage(runState, 50f), new StatePourcentage(dashState, 50f));

    toIdleTransition = new Transition(() =>
    {
        return stateManager.GetCurrentState().isStateFinished;
    }, new StatePourcentage(idle, 100));

    finishRunning = new Transition(() =>
    {
        return (ThresholdDistance >= Vector2.Distance(transform.position, player.position));
    }, new StatePourcentage(idle, 100));

    stateManager.AddStateTransition(idle, FarAwayTransition);
    stateManager.AddStateTransition(dashState, toIdleTransition);
    stateManager.AddStateTransition(runState, finishRunning);
}

Explication

Initialisation de l'état :

Les variables idle et runState sont initialisées avec leurs états respectifs. La variable idle est une instance de IdleState avec l'animateur passé en paramètre, tandis que runState est une instance de RunState qui inclut un Rigidbody2D, un Animator, un Transform pour le joueur, et une valeur de vitesse.

Initialisation du StateManager :

stateManager = new StateManager(idle); Le StateManager est initialisé avec l'état idle comme état de départ.

Définitions des transitions :

  • FarAwayTransition : FarAwayTransition = new Transition(() => { return (ThresholdDistance < Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(runState, 50f), new StatePourcentage(dashState, 50f));; Cette transition vérifie si le joueur est plus éloigné que ThresholdDistance ;

  • toIdleTransition : toIdleTransition = new Transition(() => { return stateManager.GetCurrentState().isStateFinished; }, new StatePourcentage(idle, 100)); Cette transition vérifie si l'état actuel est terminé. Si c'est le cas, elle passe à l'état idle avec une probabilité de 100 %.

  • finishRunning : finishRunning = new Transition(() => { return (ThresholdDistance >= Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(idle, 100)); Cette transition vérifie si le joueur est plus proche que ThresholdDistance. Si c'est le cas, elle passe à l'état idle avec une probabilité de 100 %.

Ajout des transitions au StateManager :

stateManager.AddStateTransition(idle, FarAwayTransition);
stateManager.AddStateTransition(dashState, toIdleTransition);
stateManager.AddStateTransition(runState, finishRunning);

Ces lignes ajoutent les transitions définies au stateManager.

Pourquoi avons-nous procédé ainsi

Changements d'état dynamiques :

Les transitions permettent à l'ennemi de modifier dynamiquement son comportement en fonction de la position du joueur et de l'état d'avancement de l'état actuel, rendant l'ennemi plus réactif et interactif dans l'environnement du jeu.

Transitions conditionnelles :

L'utilisation de conditions (comme la vérification de la distance ou de l'achèvement de l'état) garantit que les transitions d'état se produisent de manière logique et appropriée, renforçant le réalisme du gameplay.

Transitions basées sur la probabilité :

L'utilisation de StatePourcentage permet des transitions basées sur la probabilité, ajoutant un élément d'imprévisibilité et de variété au comportement de l'ennemi.

question mark

Que se passe-t-il pour l'animator lorsque la méthode StartState est appelée dans la classe RunState ?

Select the correct answer

Tout était clair ?

Comment pouvons-nous l'améliorer ?

Merci pour vos commentaires !

Section 3. Chapitre 5

Demandez à l'IA

expand

Demandez à l'IA

ChatGPT

Posez n'importe quelle question ou essayez l'une des questions suggérées pour commencer notre discussion

course content

Contenu du cours

Jeu de Combat dans Unity

Jeu de Combat dans Unity

1. Système d'Animation Unity
2. Comportement du Joueur
3. Comportement de l'Ennemi
4. Améliorer le Jeu
5. Améliorer le Jeu Flappy Bird

book
État de Course

public abstract class State
{
    public bool isStateFinished;

    public abstract void StartState();
    public virtual void UpdateState()
    {
    }
    public abstract void EndState();
    public virtual void FinishState()
    {
        isStateFinished = true;
    }
}

Modifications et ajouts

Variable isStateFinished :

Variable booléenne indiquant si l’état a terminé son exécution.

Méthode FinishState :

Nouvelle méthode virtuelle qui définit isStateFinished à true. Le fait qu’elle soit virtuelle permet aux classes dérivées de la redéfinir si des actions supplémentaires sont nécessaires à la fin d’un état.

Raisons de ces modifications

Les modifications introduisent la variable isStateFinished pour suivre l’achèvement de l’état et la méthode FinishState pour standardiser le signalement de la fin d’un état, permettant ainsi aux classes dérivées d’ajouter une logique personnalisée lors de la complétion de l’état.

État de course

public class RunState : State
{
    Rigidbody2D rb;
    Animator animator;
    Transform player;
    float speed;
    Vector2 scale;
    Vector2 velocity;

    public RunState(Rigidbody2D rb, Animator animator, Transform p, float speed)
    {
        this.animator = animator;
        player = p;
        this.speed = speed;
        this.rb = rb;
        scale = rb.transform.localScale;
        velocity = new Vector2();
    }

    public override void StartState()
    {
        isStateFinished = false;
        animator.SetBool("run", true);
    }

    public override void UpdateState(float DeltaTime)
    {
        scale.x = rb.position.x > player.position.x ? -1 : 1;
        rb.transform.localScale = scale;

        velocity.x = scale.x * speed;
        rb.velocity = velocity;
    }

    public override void EndState()
    {
        animator.SetBool("run", false);
    }
}

Examinons la classe RunState, qui hérite de la classe State. Cette classe est responsable de la gestion du comportement de course de notre ennemi. Nous allons nous concentrer sur les ajouts et modifications apportés à cette classe.

Constructeur :

public RunState(Rigidbody2D rb, Animator animator, Transform p, float speed);

Ce constructeur initialise le RunState avec les composants nécessaires : un Rigidbody2D pour le déplacement, un Animator pour les animations, un Transform pour suivre le joueur, et une speed pour la vitesse de déplacement de l’ennemi ;

Méthode StartState :

public override void StartState(); Cette méthode définit isStateFinished sur false et déclenche l’animation de course en activant le paramètre booléen "run" dans l’animator à true.

Méthode UpdateState :

public override void UpdateState(float DeltaTime); Cette méthode met à jour la position et l’orientation de l’ennemi en fonction de la position du joueur ; Elle ajuste l’échelle de l’ennemi pour qu’il fasse face au joueur, calcule la vélocité en fonction de la vitesse, et applique cette vélocité au Rigidbody2D.

Méthode EndState :

public override void EndState() Cette méthode arrête l'animation de course en définissant le paramètre booléen "run" dans l'Animator à false.

Fonctionnement pour notre ennemi

  • Déplacement et animation : En utilisant Rigidbody2D et Animator, le RunState permet à l'ennemi de se déplacer de manière fluide avec des animations correspondantes. Ce comportement assure un réalisme visuel et physique ;

  • Suivi de la position du joueur : Le transform du player permet à l'ennemi de toujours se diriger vers le joueur, ce qui est essentiel pour les comportements de poursuite ou de fuite ;

  • Gestion de la direction : L'ajustement du scale.x en fonction de la position du joueur garantit que l'ennemi fait toujours face au joueur pendant la course, renforçant ainsi le réalisme ;

  • Mises à jour dynamiques de l'état : La méthode UpdateState est appelée à chaque frame pour ajuster en continu le mouvement et la direction de l'ennemi selon la position du joueur, rendant l'ennemi réactif et dynamique.

Initialisation de l'ennemi

private void Start()
{
    idle = new IdleState(animator);
    runState = new RunState(GetComponent<Rigidbody2D>(), animator, player, speed);
    stateManager = new StateManager(idle);

    FarAwayTransition = new Transition(() =>
    {
        return (ThresholdDistance < Vector2.Distance(transform.position, player.position));
    }, new StatePourcentage(runState, 50f), new StatePourcentage(dashState, 50f));

    toIdleTransition = new Transition(() =>
    {
        return stateManager.GetCurrentState().isStateFinished;
    }, new StatePourcentage(idle, 100));

    finishRunning = new Transition(() =>
    {
        return (ThresholdDistance >= Vector2.Distance(transform.position, player.position));
    }, new StatePourcentage(idle, 100));

    stateManager.AddStateTransition(idle, FarAwayTransition);
    stateManager.AddStateTransition(dashState, toIdleTransition);
    stateManager.AddStateTransition(runState, finishRunning);
}

Explication

Initialisation de l'état :

Les variables idle et runState sont initialisées avec leurs états respectifs. La variable idle est une instance de IdleState avec l'animateur passé en paramètre, tandis que runState est une instance de RunState qui inclut un Rigidbody2D, un Animator, un Transform pour le joueur, et une valeur de vitesse.

Initialisation du StateManager :

stateManager = new StateManager(idle); Le StateManager est initialisé avec l'état idle comme état de départ.

Définitions des transitions :

  • FarAwayTransition : FarAwayTransition = new Transition(() => { return (ThresholdDistance < Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(runState, 50f), new StatePourcentage(dashState, 50f));; Cette transition vérifie si le joueur est plus éloigné que ThresholdDistance ;

  • toIdleTransition : toIdleTransition = new Transition(() => { return stateManager.GetCurrentState().isStateFinished; }, new StatePourcentage(idle, 100)); Cette transition vérifie si l'état actuel est terminé. Si c'est le cas, elle passe à l'état idle avec une probabilité de 100 %.

  • finishRunning : finishRunning = new Transition(() => { return (ThresholdDistance >= Vector2.Distance(transform.position, player.position)); }, new StatePourcentage(idle, 100)); Cette transition vérifie si le joueur est plus proche que ThresholdDistance. Si c'est le cas, elle passe à l'état idle avec une probabilité de 100 %.

Ajout des transitions au StateManager :

stateManager.AddStateTransition(idle, FarAwayTransition);
stateManager.AddStateTransition(dashState, toIdleTransition);
stateManager.AddStateTransition(runState, finishRunning);

Ces lignes ajoutent les transitions définies au stateManager.

Pourquoi avons-nous procédé ainsi

Changements d'état dynamiques :

Les transitions permettent à l'ennemi de modifier dynamiquement son comportement en fonction de la position du joueur et de l'état d'avancement de l'état actuel, rendant l'ennemi plus réactif et interactif dans l'environnement du jeu.

Transitions conditionnelles :

L'utilisation de conditions (comme la vérification de la distance ou de l'achèvement de l'état) garantit que les transitions d'état se produisent de manière logique et appropriée, renforçant le réalisme du gameplay.

Transitions basées sur la probabilité :

L'utilisation de StatePourcentage permet des transitions basées sur la probabilité, ajoutant un élément d'imprévisibilité et de variété au comportement de l'ennemi.

question mark

Que se passe-t-il pour l'animator lorsque la méthode StartState est appelée dans la classe RunState ?

Select the correct answer

Tout était clair ?

Comment pouvons-nous l'améliorer ?

Merci pour vos commentaires !

Section 3. Chapitre 5
some-alt