[DB-AL] récupérer la valeur d'une variable d'un autre script

Pour les scripts écrits en C#
Règles du forum
Merci de respecter la NOMENCLATURE suivante pour vos TITRES de messages :

Commencez par le niveau de vos scripts
DB = Débutant
MY = Moyen
CF = Confirmé

Puis le domaine d'application
-RS = Réseau
-AL = Algorithmie

Exemple :

[DB-RS] Mouvement perso multijoueur
PatateDuDimanche
Messages : 5
Inscription : 15 Déc 2020 15:51

[DB-AL] récupérer la valeur d'une variable d'un autre script

Message par PatateDuDimanche » 17 Déc 2020 12:07

Bonjour,

Je tiens à m'excuser premièrement pour cette question, oh je sais combien fatigante... je traîne sur les forums depuis plusieurs jours pour trouver des solutions et j'en ai vu pleins, j'ai regardé plusieurs tutos vidéo mais ça ne fonctionne toujours pas et je commence franchement à désespérer :pleur4:

Alors oui c'est la base et oui j'ai loupé un truc et c'est justement pour cette raison que je viens vers vous : où est l'erreur ? J'ai vu et revu mon code et je ne comprend toujours pas, où est-ce que je me trompe ?

S'il vous plaît, soyez indulgent... je sais très bien que cette question amène des tensions dû à sa simplicité mais je vous assure que j'ai cherché et je ne comprend toujours pas...

Je n'arrive pas à récupérer la valeur de ma variable int nbEnemy

voici ce que j'ai écrit dans mon script Timer :

Code : Tout sélectionner

public int nbEnemy; 

void Start()
{
        nbEnemy = GameObject.Find("Player").GetComponent("GameOver").nbEnemy();
}

void Update()
    {

     	stopwatchcalcul ();  

     	if(nbEnemy==0)
     	{
     		stopTimer();
     	} 
    }
Dans mon script GameOver :

Code : Tout sélectionner

public int nbEnemy = 0;
Voici l'erreur que j'obtiens :

Code : Tout sélectionner

Assets\Scripts\Interface\stopwatchTimer.cs(25,70): error CS1061: 'Component' does not contain a definition for 'nbEnemy' and no accessible extension method 'nbEnemy' accepting a first argument of type 'Component' could be found (are you missing a using directive or an assembly reference?)

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6214
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: [DB-AL] récupérer la valeur d'une variable d'un autre script

Message par boubouk50 » 17 Déc 2020 12:44

Code : Tout sélectionner

nbEnemy = GameObject.Find("Player").GetComponent("GameOver").nbEnemy();
Décortiquons cela:
tu vas chercher un gameObject nommé Player qui possède un Component GameOver qui définit une fonction nommée nbEnemy ().
Et là, tu me dis, mais non, pas une fonction, un entier... Et tu te rends compte de ton erreur.
C'est nbEnemy que tu veux, pas nbEnemy().
Aussi, tu ne récupères que la donnée à l'instant t et pas une référence de la donnée. Il te faut pointer sur l'entier et ne pas copier sa valeur.

Code : Tout sélectionner

public GameOver enemyGameOver = null; 

void Start()
{
	//tu récupères le component pour pouvoir y accéder à tout moment
        enemyGameOver = GameObject.Find("Player").GetComponent("GameOver");
}

void Update()
{
     	stopwatchcalcul ();  

     	if(enemyGameOver.nbEnemy == 0)
     	{
     		stopTimer();
     	} 
}
Ceci est fonctionnel. Maintenant dans l'architecture, c'est moche. En effet, tu récupères une donnée externe pour la tester à chaque frame afin de stopper un timer.
C'est comme quand tu es dans une voiture et que tu demandes en boucle au conducteur:
on est arrivé?
-Non
on est arrivé?
-Non
[... le temps passe...]
on est arrivé?
-Oui
on est arrivé?
-Oui
[...ad vitam eternam...]

Il serait beaucoup plus judicieux de faire l'inverse, c'est à dire de simplement attendre qu'on te dise quand il vaut 0. Ce qui revient à faire:
Conducteur, dites moi quand on est arrivé, svp.
[... le temps passe...]
- On est arrivé.

Donc c'est à ton component GameOver de gérer le nbEnemy == 0 et de le dire à ton Component Timer. Par un event, pour ne pas lier directement les Components, ou par une référence publique depuis l'inspecteur ou enfin par un Find (à utiliser avec parcimonie)
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

PatateDuDimanche
Messages : 5
Inscription : 15 Déc 2020 15:51

Re: [DB-AL] récupérer la valeur d'une variable d'un autre script

Message par PatateDuDimanche » 17 Déc 2020 15:54

Merci pour ce magnifique dialogue :hehe:

C'est beaucoup plus clair pour moi :gene:

Cependant je ne suis pas super à l'aise avec le code et je n'ose pas trop toucher :gene: je sais que c'est mal de dire ça mais tant que ça fonctionne c'est le plus important :gene: j'ai toujours peur de tout faire bugguer en essayant de trop mettre les mains dans le cambouis...

J'ai essayé de copier le code que tu as écrit mais malheureusement j'obtiens toujours la même erreur :

Code : Tout sélectionner

Assets\Scripts\Interface\stopwatchTimer.cs(24,25): error CS0266: Cannot implicitly convert type 'UnityEngine.Component' to 'GameOver'. An explicit conversion exists (are you missing a cast?)
L'erreur viens de cette fameuse ligne :

Code : Tout sélectionner

enemyGameOver = GameObject.Find("Player").GetComponent("GameOver");
Tu as l'air de dire que normalement ça fonctionne de ce fait, où est ce que je me trompe ? Même en faisant un copier-coller j'arrive quand même à faire des erreurs :triste1:

Je remercie pour ta patience :gene3:

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 6214
Inscription : 28 Avr 2014 11:57
Localisation : Saint-Didier-en-Bresse (71)

Re: [DB-AL] récupérer la valeur d'une variable d'un autre script

Message par boubouk50 » 17 Déc 2020 17:04

Je l'ai fait à main levée, donc il est possible qu'il y ait une erreur, rassure-toi.

Code : Tout sélectionner

enemyGameOver = GameObject.Find("Player").GetComponent("GameOver");
Ici, j'ai supposé que GetComponent("GameOver") renverrait un objet de type GameOver, mais il renvoie un Component, d'où l'erreur.
Soit tu dois le caster en GameObject:

Code : Tout sélectionner

enemyGameOver = GameObject.Find("Player").GetComponent("GameOver") as GameOver;
Soit tu utilises l'autre GetComponent qui est typé:

Code : Tout sélectionner

enemyGameOver = GameObject.Find("Player").GetComponent<GameOver>();
Concernant l'idée que "tant que ça marche ça me va" tu n'en es que le seul décideur.
Un vieux vélo rouillé sans frein avec le pédalier qui claque et des pneus sous-gonflés t'emmènera chercher le pain "aussi bien" qu'un vélo entretenu.
"Ce n'est pas en améliorant la bougie, que l'on a inventé l'ampoule, c'est en marchant longtemps."
Nétiquette du forum
Savoir faire une recherche
Apprendre la programmation

Répondre

Revenir vers « (C#) CSharp »