Exercice 1: Bases C#, Simulation d'un combat RPG --- Système de tour par tour

Il est maintenant temps de travailler sur notre système de combat !

Avant de commencer à programmer notre système, prenons un moment pour dresser une liste de nos besoins.

  • Nous avons besoin de savoir si c'est le tour du joueur.
  • Le joueur peut effectuer une action une seule fois, puis c'est au tour de l'ennemi, avant de revenir au joueur.
  • Nous pourrions utiliser une variable de type bool pour indiquer si c'est le tour du joueur.
  • Nous devrons également accéder aux propriétés de nos personnages.
  • Le système doit être capable d'identifier quel bouton a été pressé pendant le tour du joueur.
  • Le système se met à jour lorsque nous effectuons des actions, donc la méthode Update() ne sera pas nécessaire et pourra être retirée.

Création du script "BattleSystem"

Nous allons créer un script nommé "BattleSystem". Notez qu'il existe une multitude de façons de créer notre système de combat. Nous pourrions très bien tout intégrer dans le script "Joueur". Cependant, il est généralement préférable de dédier un script à une seule tâche, même si cela peut légèrement complexifier le développement.

Bref, dans notre script "BattleSystem", nous allons utiliser une variable de type bool appelée tourDuJoueur pour déterminer si c'est le tour du joueur. Lorsque c'est le tour du joueur, cette variable sera vraie ; sinon, elle sera fausse, indiquant que c'est le tour de l'ennemi. Vous devriez donc avoir un code similaire à celui-ci :

using UnityEngine;

public class BattleSystem : MonoBehaviour
{
    private bool tourDuJoueur = true;
    
    void Start()
    {
        
    }

}

Ensuite, nous allons créer une variable int pour identifier quel bouton a été pressé. Nous l'utiliserons plus tard dans une condition pour déclencher la méthode correspondante.

using UnityEngine;

public class BattleSystem : MonoBehaviour
{
	private bool tourDuJoueur = true;
	private int idAction; // 1 = attaque, 2 = magie, 3 = esquive

    void Start()
    {
        
    }

}

Ajoutons ensuite deux variables de type GameObject pour accéder aux propriétés de nos personnages.

using UnityEngine;

public class BattleSystem : MonoBehaviour
{
	private bool tourDuJoueur = true;
	private int idAction; // 1 = attaque, 2 = magie, 3 = esquive

	[SerializeField] GameObject joueur;
	[SerializeField] GameObject ennemie;


    void Start()
    {
        
    }

}

Enfin, nous allons créer un objet vide(type empty) dans notre scène et y ajouter le script comme composant.

Identifier le bouton déclencheur

Il est possible d'obtenir le nom du bouton ayant déclenché un événement, mais ce n'est pas encore à votre niveau. Nous l'apprendrons dans un prochain chapitre. Pour l'instant, nous utiliserons des méthodes différentes pour chaque bouton, qui affecteront un nombre dans la variable idAction.

Ainsi, nous aurons quelque chose de ce type :

using UnityEngine;

public class BattleSystem : MonoBehaviour
{
	private bool tourDuJoueur = true;
	private int idAction; // 1 = attaque, 2 = magie, 3 = esquive

[SerializeField] GameObject joueur; [SerializeField] GameObject ennemie;     void Start() { } public void boutonAttaque() { idAction = 1; } public void boutonMagie() { idAction = 2; } public void boutonEsquive() { idAction = 3; } }

Nous utiliserons ensuite la variable idAction pour déterminer quel bouton a été pressé. N'oubliez pas de mettre à jour les méthodes OnClick de vos trois boutons !

Création de la méthode principale du système

Nous allons maintenant créer notre méthode principale, qui sera déclenchée lorsqu'un bouton est pressé.

Avant de pouvoir choisir une action, nous devons d'abord vérifier si c'est le tour du joueur. Nous allons donc écrire une condition à l'intérieur. De plus, nous ne voulons pas qu'un joueur puisse appuyer plusieurs fois sur les boutons durant son tour. Nous allons donc ajouter une condition pour lancer la méthode combatSystem dans nos trois boutons uniquement lorsque c'est le tour du joueur. Cela donne le code suivant :

using UnityEngine;

public class BattleSystem : MonoBehaviour
{
	private bool tourDuJoueur = true;
	private int idAction; // 1 = attaque, 2 = magie, 3 = esquive

	[SerializeField] GameObject joueur;
	[SerializeField] GameObject ennemie;


    void Start()
    {
        
    }

	private void combatSystem()
	{
	    if(tourDuJoueur)// si c'est le tour du joueur
	    {
} else // si c'est le tour de l'ennemie. {
} }
public void boutonAttaque() { idAction = 1;

if(tourDuJoueur)// si c'est le tour du joueur { combatSystem(); // Enclenche le système de combat seulement si c'est le tour du joueur.             } } public void boutonMagie() { idAction = 2;

if(tourDuJoueur)// si c'est le tour du joueur { combatSystem(); // Enclenche le système de combat seulement si c'est le tour du joueur.             }         } public void boutonEsquive() { idAction = 3;

if(tourDuJoueur)// si c'est le tour du joueur { combatSystem(); // Enclenche le système de combat seulement si c'est le tour du joueur.             }         } }

Ainsi, si c'est le tour du joueur, seule la première partie du bloc sera exécutée, et l'action du joueur sera lancée. Si ce n'est pas le tour du joueur, rien ne se passe. 

Activer l'attaque du joueur

Pour déterminer quelle action le joueur va effectuer pendant son tour, nous allons vérifier la valeur de la variable idAction. En effet, cette valeur change chaque fois qu'un des trois boutons est pressé, ce qui nous permet de savoir ce que le joueur souhaite faire.

Nous allons ajouter une condition dans notre méthode combatSystem pour activer l'une des actions du joueur en fonction de la valeur de idAction. Cela donne le code suivant :

using UnityEngine;

public class BattleSystem : MonoBehaviour
{
	private bool tourDuJoueur = true;
	private int idAction; // 1 = attaque, 2 = magie, 3 = esquive

	[SerializeField] GameObject joueur;
	[SerializeField] GameObject ennemie;


    void Start()
    {
        
    }

	private void combatSystem()
	{
		if(tourDuJoueur)// si c'est le tour du joueur
		{
			if(idAction == 1)
			{
				joueur.GetComponent<Joueur>().Attaquer();
			}
			else if(idAction == 2)
			{
				joueur.GetComponent<Joueur>().Magie();
			}
			else if(idAction == 3)
			{
				joueur.GetComponent<Joueur>().Esquive();
			}
			
		}
		else // si c'est le tour de l'ennemie.
		{
		}

	}
public void boutonAttaque() { idAction = 1; if(tourDuJoueur)// si c'est le tour du joueur { combatSystem(); // Enclenche le système de combat seulement si c'est le tour du joueur.             } } public void boutonMagie() { idAction = 2; if(tourDuJoueur)// si c'est le tour du joueur { combatSystem(); // Enclenche le système de combat seulement si c'est le tour du joueur.             }         } public void boutonEsquive() { idAction = 3; if(tourDuJoueur)// si c'est le tour du joueur { combatSystem(); // Enclenche le système de combat seulement si c'est le tour du joueur.             }         } }

Passer au tour de l'ennemi

Une fois l'action du joueur terminée, il faut indiquer que c'est au tour de l'ennemi. Lorsque le joueur a terminé son action, nous allons changer la valeur de tourDuJoueur à false et relancer la méthode. Cela permettra de déclencher l'action de l'ennemi.

using UnityEngine;

public class BattleSystem : MonoBehaviour
{
	private bool tourDuJoueur = true;
	private int idAction; // 1 = attaque, 2 = magie, 3 = esquive

	[SerializeField] GameObject joueur;
	[SerializeField] GameObject ennemie;


    void Start()
    {
        
    }

	private void combatSystem()
	{
		if(tourDuJoueur)// si c'est le tour du joueur
		{
			if(idAction == 1)
			{
				joueur.GetComponent<Joueur>().Attaquer();
			}
			else if(idAction == 2)
			{
				joueur.GetComponent<Joueur>().Magie();
			}
			else if(idAction == 3)
			{
				joueur.GetComponent<Joueur>().Esquive();
			}

			tourDuJoueur = false;
			combatSystem(); // relance la méthode
			
		}
		else // si c'est le tour de l'ennemie.
		{
		}

	}

public void boutonAttaque() { idAction = 1; if(tourDuJoueur)// si c'est le tour du joueur { combatSystem(); // Enclenche le système de combat seulement si c'est le tour du joueur.             } } public void boutonMagie() { idAction = 2; if(tourDuJoueur)// si c'est le tour du joueur { combatSystem(); // Enclenche le système de combat seulement si c'est le tour du joueur.             }         } public void boutonEsquive() { idAction = 3; if(tourDuJoueur)// si c'est le tour du joueur { combatSystem(); // Enclenche le système de combat seulement si c'est le tour du joueur.             }         } }

Comme vous pouvez l'observer, il n'est pas interdit d'appeler une méthode qui s'exécute elle-même. Cela aura pour effet de relancer la méthode combatSystem, mais cette fois, comme la valeur de tourDuJoueur est fausse, nous exécuterons uniquement le bloc dédié au tour de l'ennemi. 

Action de notre ennemi et fin de tour.

Cette fois, c'est simple : nous allons appeler la méthode qui permet à notre IA de choisir une attaque, puis indiquer que le tour de l'ennemi est terminé en modifiant la variable tourDuJoueur. Voici ce que cela donne.

using UnityEngine;

public class BattleSystem : MonoBehaviour
{
	private bool tourDuJoueur = true;
	private int idAction; // 1 = attaque, 2 = magie, 3 = esquive

	[SerializeField] GameObject joueur;
	[SerializeField] GameObject ennemie;

	private void combatSystem()
	{
		if(tourDuJoueur)// si c'est le tour du joueur
		{
			if(idAction == 1)
			{
				joueur.GetComponent<Joueur>().Attaquer();
			}
			else if(idAction == 2)
			{
				joueur.GetComponent<Joueur>().Magie();
			}
			else if(idAction == 3)
			{
				joueur.GetComponent<Joueur>().Esquive();
			}

			tourDuJoueur = false;
			combatSystem(); // relance la méthode
			
		}
		else // si c'est le tour de l'ennemie.
		{
			ennemie.GetComponent<Ennemie>().ChoisirUneAttaque(); // exécute la méthode ChoisirUneAttaque() du script ennemie
			tourDuJoueur = true;
		}

	}

public void boutonAttaque() { idAction = 1; if(tourDuJoueur)// si c'est le tour du joueur { combatSystem(); // Enclenche le système de combat seulement si c'est le tour du joueur.             } } public void boutonMagie() { idAction = 2; if(tourDuJoueur)// si c'est le tour du joueur { combatSystem(); // Enclenche le système de combat seulement si c'est le tour du joueur.             }         } public void boutonEsquive() { idAction = 3; if(tourDuJoueur)// si c'est le tour du joueur { combatSystem(); // Enclenche le système de combat seulement si c'est le tour du joueur.             }         } }

Penser à ajouter des Debug.Log dans les méthodes utilisées par le joueur et l'ennemi afin de vérifier que tout fonctionne comme prévu.

Après vérification, nous constatons que l'action du joueur est bien exécutée lorsque nous appuyons sur un bouton, suivie de l'attaque de l'ennemi.

Conclusion

Nous avons terminé notre script de gestion de combat. Dans cette page, vous avez pu pratiquer la programmation, notamment l'utilisation des variables de type bool. Vous avez également appris une méthode détournée pour identifier le bouton ayant exécuté le script.

Courage, nous avons presque terminé. Pour la suite du cours, il nous restera à gérer la mort de nos personnages, à programmer les attaques et pour finir à créer l'intelligence artificielle de notre ennemi.

Rendez-vous dans la prochain page pour apprendre à "Tuer" un personnage.

Cette page ne contient pas de Fichier à Télécharger.

Les cours vous ont aidé et vous souhaitez à votre tour nous aider ?

- - - Vous pouvez partager le site avec vos connaissances, ainsi que le Discord. - - -

- - - Participer à la vie active du site et du Discord. - - -

- - - Faire un petit don pour nous aider à payer le serveur avec le lien ci-dessous. - - -

Buy Me a Coffee at ko-fi.com