Exercice 1: Bases C#, Simulation d'un combat RPG --- Référence à un GameObject.

Introduction à la gestion des références entre GameObjects

Dans les pages précédentes, nous avons préparé nos personnages. À présent, nous allons apprendre à faire en sorte qu'un personnage puisse interagir avec les composants d'un autre.

Remarque : Nous allons effectuer plusieurs modifications de nos scripts à des fins d'exercice. Pour vous faciliter la tâche, à la fin de cette page, je vous fournirai les scripts complets que vous devrez utiliser pour la suite du cours.

Obtenir une référence à un GameObject

Dans Unity, tous les objets présents dans la hiérarchie, qu'il s'agisse de cubes, de modèles 3D, d'images, etc., sont appelés des GameObject.

Pour obtenir une référence à un GameObject spécifique de votre scène, il suffit de créer une variable de type GameObject. Par exemple, dans le script "Joueur", vous pouvez ajouter ceci :

using UnityEngine;

public class Joueur : MonoBehaviour
{
    public int vie;
    private int mana = 20;
    [SerializeField] int force;

    public GameObject cible; // Créer la variable qui contiendra notre référence. 
void Start() { } void Update() { } void Attaquer() { } void Magie() { } void Esquive() { } void Mort() { } }

 La ligne public GameObject cible; déclare une variable publique qui pourra stocker une référence d'un GameObject de votre scène. Nous utiliserons plus tard cette variable pour déterminer quelle est la cible des attaques de nos deux personnages. 

Ajouter un GameObject à la variable cible 

Méthode pour variable publique: Comme notre variable cible est publique, vous pouvez simplement glisser-déposer le GameObject depuis la hiérarchie jusqu'au nom de la variable dans l’inspecteur. Assurez-vous que l’objet contenant le script du joueur est sélectionné pendant cette opération, sans changer de sélection.

Que faire si la variable est privée ?

Il existe plusieurs façons de le faire par code. Pour ne pas alourdir ce cours, nous en explorerons qu'une seule pour le moment. D’autres méthodes seront abordées au fur et à mesure de la formation.

Si la variable est privée, vous pouvez lui assigner une référence par code en utilisant la méthode GameObject.Find(), qui permet de rechercher(find) un GameObject par son nom dans la hiérarchie. Voici un exemple :

using UnityEngine;

public class Joueur : MonoBehaviour
{
    public int vie;
    private int mana = 20;
[SerializeField] int force; private GameObject cible; void Start() {         cible = GameObject.Find("Ennemie");     } void Update() { } void Attaquer() { } void Magie() { } void Esquive() { } void Mort() { } }

 

Explication : La ligne cible = GameObject.Find("Ennemie"); recherche un GameObject nommé "Ennemie" et l’affecte à la variable cible.

Remarque : Assurez-vous d’effectuer cette recherche dans des méthodes telles que Start() ou Awake(), car GameObject.Find() ne doit pas être utilisé pour initialiser directement une variable. Cela peut entraîner des problèmes de référence, car, lors du démarrage d'une scène, votre GameObject n'existe pas immédiatement ; il doit d'abord être "chargé", donc il sera introvable si vous faite une recherche trop tôt. 

Comment ne pas oublier ce que vous apprenez ?

Si vous oubliez comment effectuer une opération spécifique, pensez à faire une recherche sur Google… ou à poser votre question à une IA comme ChatGPT. Pour des résultats plus rapide, il est préférable d’utiliser ChatGPT, surtout pour des questions liées à Unity.Deplus, les réponses seront probablement en anglais si vous chercher dans google. N'oubliez pas de préciser à ChatGPT que vous utilisez Unity afin d’obtenir des réponses adaptées.

Un bon programmeur est un programmeur qui sait faire des recherches. Il est normal de ne pas connaître par cœur les millions de méthodes et objets disponibles dans les bibliothèques. Les plus importants viendront avec la pratique, et les autres pourront être trouvés grâce à des recherches. 

Une fois que vous avez trouvé la méthode recherchée, consultez la documentation officielle d’Unity pour vous assurer qu’elle est adaptée à votre projet et pour vérifier qu’il n’y a pas d'informations supplémentaires à prendre en compte. Par exemple, Unity recommande d’utiliser GameObject.Find() dans Start() pour des raisons de performance, un détail que ChatGPT pourrait ne pas mentionner. Ne copiez pas bêtement le code donné par ChatGPT sans vérifier. 

Modifier un composant à partir d'une référence

Une fois que vous avez une référence à votre GameObject, vous devez indiquer quel composant vous souhaitez modifier et quelles valeurs y appliquer.

Commençons par le composant le plus simple, donc le composant Transform, qui détermine la position d’un GameObject.

Voici comment procéder :

using UnityEngine;

public class Joueur : MonoBehaviour
{
    public int vie;
	private int mana = 20;
	[SerializeField] int force;

	private GameObject cible;

    void Start()
    {
cible = GameObject.Find("Ennemie")       cible.transform.position = new Vector3(1,1,1); // Modifie la position de la cible. } void Update() { } void Attaquer() { } void Magie() { } void Esquive() { } void Mort() { } }

La ligne cible.transform.position = new Vector3(1, 1, 1); modifie la position du composant Transform du GameObject assigné à la variable cible.

 

Astuce : Dans la majorité des cas, vous pouvez facilement identifier le nom des propriétés à écrire dans votre code en observant l'inspecteur. Par exemple, pour le composant Transform, vous voyez la propriété Position. Ensuite, dans le cas de la position, vous pouvez observer 3 nombres, en mathémathiques cela s'appelle un Vector3, puisque la position dans un monde 3D à 3 dimensions, un Vector3 représente donc sa position dans l'espace. Ce qui nous permet de déterminer facilement quoi écrire à notre variable cible  cible.transform.position = new Vector3(1, 1, 1); 

Dans le cas d'un Vector3, vous devez en créer un avec la ligne new Vector3(x, y, z) car il s'agit en réalité d'un objet. Vous remplacerez bien sûr les x, y, z par les valeurs souhaitées. Pour l'instant, ne vous attardez pas trop sur le mot-clé new. Nous en apprendrons plus sur ce mot-clé une autre fois. Souvenez-vous seulement que, pour utiliser un Vector3, vous devez utiliser le mot-clé new devant. Si la valeur devait être simplement un nombre, par exemple de type int, alors il ne serait pas nécessaire d'ajouter le mot-clé new.

Testez maintenant votre code.

Comme vous pouvez le voir, le composant Position de notre cible a bien été modifié avec les valeurs 1, 1, 1 lorsque nous lançons le jeu. 

 

Modifier d'autres composants

Nous avons commencé par le composant le plus simple, Transform. Pour modifier d’autres composants, vous devez utiliser une méthode spécifique pour récupérer le composant désiré, y compris les scripts.

Utilisez la méthode GetComponent<Nom du composant>(), où l'intérieur des <> contient le nom du composant que vous souhaitez modifier. Par exemple :

using UnityEngine;

public class Joueur : MonoBehaviour
{
    public int vie;
	private int mana = 20;
	[SerializeField] int force;

	private GameObject cible;

    void Start()
    {
	cible = GameObject.Find("Ennemie");
        cible.GetComponent<Ennemie>().vie = 99;
Debug.log(cible.GetComponent<Ennemie>().vie)  // Affiche la variable vie du script Ennemie de la cible, donc 99 comme nous l'avons modifiée précédemment.     } void Update() { } void Attaquer() { } void Magie() { } void Esquive() { } void Mort() { } }

Explication : La ligne cible.GetComponent<Ennemie>().vie = 99; modifie la propriété vie du script Ennemie attaché à l'objet cible.

Testez le code et vérifiez que la valeur de vie du script Ennemie est bien modifiée.

Et voila! votre script Joueur à réussi a modifier la valeur de la variable vie du Script Ennemie que possède le deuxième personnage! Vous venez d'apprendre l'une des techniques les plus importantes pour créer un jeu vidéo!

Vous pouvez faire cela pour tout les composans existant. Vous voulez modifier un RigidBody par exemple ? Alors faite cible.GetComponent<RigidBody>().propritété-A-Modifier; c'est aussi simple que ça :D.

La porter des variables, une importance capitale pour y avoir access.

La ligne cible.GetComponent<Ennemie>().vie = 99; fonctionne car la variable vie dans le script Ennemie est publique. Si elle était privée, vous ne pourriez pas la modifier directement. Par exemple, la ligne

[SerializeField] int force;   

n'est pas accessibles.

Une solution consiste à utiliser une méthode publique pour modifier la valeur.

Par exemple, dans le script Ennemie, vous pouvez ajouter une méthode pour modifier la force :

using UnityEngine;

public class Ennemie : MonoBehaviour
{
	public int vie;
	[SerializeField] int force;   

        public void ModifierForce()
        {
            force = 2;
        }

}

Et ensuite dans le script Joueur, vous pouvez appeler cette méthode : 

using UnityEngine;

public class Joueur : MonoBehaviour
{
    public int vie;
    private int mana = 20;
    [SerializeField] int force;

    private GameObject cible;

    void Start()
    {
	cible = GameObject.Find("Ennemie");
        cible.GetComponent<Ennemie>().ModifierForce();  // Active la méthode ModifierForce() du script Ennemie. 
    }


}

Cette méthode est un exemple de ce qu'on appelle en programmation des setters/getters. Il est généralement recommandé de mettre les variables en privées et de les exposer via des méthodes publiques pour des raisons de sécurité et de gestion du code. De cette façon, si la méthode pour obtenir/modifier la valeur n'existe pas, nous pouvons être certains qu'un autre programmeur dans l'équipe ne touchera pas à une variable essentielle, car cette dernière est privée. 

Dans notre cas, nous n'utiliserons pas cela, car cela alourdirait inutilement l'exercice présent. Mais gardez en tête que si un jour vous souhaitez travailler en équipe ou avec des scripts développés par d'autres personnes, il est fort probable que vous rencontriez des setters/getters comme seul moyen de modifier une valeur.

Conclusion

Vous avez dans cette page appris comment créer des références à des GameObject et comment modifier les composants de ceux-ci à partir de votre script.

Pour la suite du cours, vos scripts devrait contenir au moins ce code.

Script Joueur:

using UnityEngine;

public class Joueur : MonoBehaviour
{
    public int vie;
	private int mana = 20;
	[SerializeField] int force;

	private GameObject cible;

    void Start()
    {
	cible = GameObject.Find("Ennemie");
    }

    
    void Update()
    {
        
    }

	void Attaquer()
	{

	}
	
	void Magie()
	{

	}

	void Esquive()
	{

	}
	
	void Mort()
	{
	}
}

Script Ennemie:

using UnityEngine;

public class Ennemie : MonoBehaviour
{
	public int vie;
	[SerializeField] int force;   
	private GameObject cible;

    void Start()
    {
        cible = GameObject.Find("Joueur");
    }
    void Update()
    {
        
    }

	void ChoisirUneAttaque()
	{
	}

	void AttaqueNormal()
	{
	}

	void AttaqueSurpuissante()
	{
	}

	void Mort()
	{
	}
}

Dans la prochaine partie du cours, nous verrons comment créer un bouton pour activer une méthode d'attaque !

À bientôt.

À la prochaine!

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