[DB] Créer une action qui se répète à X temps.

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
Sicryn
Messages : 11
Inscription : 23 Mai 2018 17:40

[DB] Créer une action qui se répète à X temps.

Message par Sicryn » 05 Mai 2019 20:42

Hello à tous,

Premier post sur ce forum, j'ai essayé de trouver une solution à mon problème dans les autres topic mais je n'ai pas réussi à le résoudre, donc j'en ouvre un nouveau.

[Tout d'abord, je suis débutant en code, je suis illustrateur à la base, et j'ai une idée de jeu qui me tient à coeur, mais pas de codeur sous la main. Et comme j'ai toujours été très intéressé par apprendre à faire du code moi même je me suis lancé dans l'aventure. J'ai donc suivi des formations, des tutos, des forums ect, et j'ai beau avoir désormais les bases ( pour au moins comprendre les codes ect ), j'ai encore énormément de mal à les créer moi même.
Je sais donc qu'essayer de faire un jeu est très prétentieux, mais je suis d'avis que c'est en essayant que j'apprendrais le mieux, et je n'ai pas peur de devoir recommencer plusieurs fois !
Tout ça pour dire que je risque de souvent demander de l'aide ... :roll: ]


Alors voilà mon problème, je veux faire un jeu de gestion ( oui je sais, ça ne va pas être simple pour un débutant ) et pour cela j'ai créé un système de jour/mois/année qui s'écoule. Je voudrais créer un système de "mensualité", pour que la sommes des "charges" soit retiré de l'argent du joueur tout les tant de jours. Pour cela j'ai utilisé une coroutine :

Code : Tout sélectionner

void Start()
  {
	  mensu = GameObject.Find("Day").GetComponent<Text>();
   }

  void Update()
  {
	  if (mensu.text == " Day: 2")
	  {
	   StartCoroutine(waitmensu());
	  }
  }

	  IEnumerator waitmensu()
  {     
	  yield return new WaitForSeconds(.1f);
	Mensualite(mensuelle);
	Update(); 
    }
Le problème est que la mensualité se répète plein de fois tout au long de la seconde que dure " Day = 2 " , au lieu de ne s’exécuter qu'une fois. Ce qui fait par exemple que cela va faire -100000 au lieu de -500.

J'ai tenter de résoudre ce problème avec une coroutine qui se lance au Start et qui attend 30sec ( le temps d'un mois ) avant de se répéter, ce qui marche bien ( dans le sens ou cela ne s'effectue bien qu'une fois avant de réattendre 30sec et de se ré exécuter ) mais là vient un autre problème, sur le long terme il y a un décalage qui se crée entre la mensualité et le calendrier ( par exemple à la longue la mensualité va s'effectuer le 29 du mois au lieu du 1er) alors que normalement mes jours durent bien 1sec, et donc il ne devrait pas y avoir de décalage qui se crée avec le WaitForSeconds ...

Dans les deux cas je ne comprend pas le problème.
J'espère avoir été clair, si vous avez besoin d'autres éléments n'hésitez pas à me demander.

Et surtout, merci d'avance à tout ceux qui me viendront en aide !!

Avatar de l’utilisateur
evereal
Messages : 109
Inscription : 06 Nov 2015 18:46

Re: [DB] Créer une action qui se répète à X temps.

Message par evereal » 06 Mai 2019 08:58

Hello,

L'explication pour ton premier problème est assez simple.
l'appel a la fonction update() se lance a peu pret 30 fois par secondes, si ton Day: 2 dure 1 seconde, tu vas créer une 30aine de coroutine qui vont chacune déduire la mensualité.

Pour ton second problème je n'ai pas d'explication, ça vient peut être du code qui gère tes journées ou tes mensualités.

Pour la logique algorithmique, je laisserai tomber cette coroutine de mensualité pour un event qui se déclenche lors du passage de day x à day x+1
“La théorie, c'est quand on sait tout et que rien ne fonctionne. La pratique, c'est quand tout fonctionne et que personne ne sait pourquoi. Ici, nous avons réuni théorie et pratique : Rien ne fonctionne... et personne ne sait pourquoi !”

Moi 1971
Messages : 727
Inscription : 29 Sep 2015 13:38

Re: [DB] Créer une action qui se répète à X temps.

Message par Moi 1971 » 06 Mai 2019 09:45

Bonjour,
je te conseille de faire comme le dit Evereal.
Si on prend ton code comme il est, il y a plein de problème de conception. Mais quand on début c'est normal.
- Pour ton deuxième problème, le code gère t'il les mois de 30 et 31 jours? 28 ou 29 jours?
- Quand tu écris :

Code : Tout sélectionner

if (mensu.text == " Day: 2")
Comment faire pour les jours 3,4,5,... et suivants et infinis?
- Comme l'update() est appelée plusieurs fois par seconde cela est inutile de l'appeler une fois de plus depuis waitmensu().
- Pour palier au problème de la coroutine lancée plusieurs fois durant le jour 2, voici une solution (c'est pour apprendre une méthode. Il ne faut pas utiliser cette façon de faire à mon avis, mais la solution dit par Evereal) Utilise un Booléen. variable prenant deux valeurs possibles (0 ou 1 // True ou False). On s'en sert comme "Flag". Tu l'appelles "pas_Encore_Lance" et tu l'initialise à "True" = "1". Au début. Tu modifie le if pour y insérer la condition supplémentaire. Puis il faut faire basculer le booléen de vrai à faut puis de faut à vrai. Et ça donne:

Code : Tout sélectionner

  private bool pas_Encore_Lance = true;

void Start()
  {
	  mensu = GameObject.Find("Day").GetComponent<Text>();
   }

  void Update()
  {
	  if (mensu.text == " Day: 2" &&  pas_Encore_Lance)
	  {
	  pas_Encore_Lance = false;
	  StartCoroutine(waitmensu());
	  }
  }

	  IEnumerator waitmensu()
  {     
	yield return new WaitForSeconds(.1f);
	Mensualite(mensuelle);
	pas_Encore_Lance = true; 
    }

Sicryn
Messages : 11
Inscription : 23 Mai 2018 17:40

Re: [DB] Créer une action qui se répète à X temps.

Message par Sicryn » 08 Mai 2019 17:35

Hello à vous deux !

Merci pour votre aide rapide !

Moi 1971 :
- Pour ton deuxième problème, le code gère t'il les mois de 30 et 31 jours? 28 ou 29 jours?
En temps normal il gère bien les mois de 30 et 31 jours mais dans ma tentative de résolution de mon problème avec WaitForSeconds, j'avais fait en sorte qu'il n'y est que des mois de 30, pour que justement cela ne casse pas tout.
- Pour palier au problème de la coroutine lancée plusieurs fois durant le jour 2, voici une solution (c'est pour apprendre une méthode. Il ne faut pas utiliser cette façon de faire à mon avis, mais la solution dit par Evereal) Utilise un Booléen. variable prenant deux valeurs possibles (0 ou 1 // True ou False). On s'en sert comme "Flag". Tu l'appelles "pas_Encore_Lance" et tu l'initialise à "True" = "1". Au début. Tu modifie le if pour y insérer la condition supplémentaire. Puis il faut faire basculer le booléen de vrai à faut puis de faut à vrai. Et ça donne:
Merci pour l'astuce ! J'ai tenté ton code pour voir comment cela fonctionnait, et cela améliore la chose mais ne la résolue pas entièrement, la mensualité ne se lance plus une trentaine de fois comme précédemment, mais encore 5/6 fois environ.. je ne sais pas si l'erreur vient de moi du coup :/

Et du coup pour ce que vous pensez tout les deux être la solution :
Pour la logique algorithmique, je laisserai tomber cette coroutine de mensualité pour un event qui se déclenche lors du passage de day x à day x+1
Je comprend l'idée que vous me dite de faire, mais je me rend compte que j'ai encore de grosses lacunes, car après un bon nombre d'essai je n'arrive pas à comprendre comment l'effectuer concrètement... Est-ce que vous pourriez développer un peu ? Pas forcement me pré-mâcher le code mais rien qu'une petite explication un peu plus concrète pour que je tilt sur la façon de faire :-| Car je pense que ce sera quelque chose de très utile pour la suite donc je veux bien le comprendre ! Ce serait top !

Merci encore et bonne journée ! ;)

Moi 1971
Messages : 727
Inscription : 29 Sep 2015 13:38

Re: [DB] Créer une action qui se répète à X temps.

Message par Moi 1971 » 09 Mai 2019 10:11

Bonjour,
... mais encore 5/6 fois environ.. je ne sais pas si l'erreur vient de moi du coup
Non, le problème est que tant que jour est égal à 2 et que le le bool RE-passe à 1 et bien le code RE-lance waitmensu().

Il faut modifier le code pour que "pas_Encore_Lance = true; "soit retiré de waitmensu() et placé quelque part dans ton code juste après l'endroit ou jour passe à 3 ( ou plus "correctement" jour = jour + 1). Parce que si la fonction " Mensualite(mensuelle); " dure moins de 1 seconde en temps d’exécution, alors le booléen repasse à 1 alors que jour est toujours = à 2...

Si tu le fais et que ce code se trouve dans un autre script il va te falloir accéder au Booléen "pas_Encore_Lance" depuis l’extérieur du script.
Une des façons est d'utiliser un event, tout dépend de ton code. Il y a plusieurs façon de faire.
Si tu utilises les "Boutons" tu peux utiliser les event au moment de cliquer sur le bouton.
Exemple ici : https://docs.unity3d.com/ScriptReferenc ... Click.html
Si c'est un script qui change les jours, tu peux utiliser UnityEvent:
Exemple : https://docs.unity3d.com/ScriptReferenc ... ent_1.html

Il y a sûrement d'autres façons de faire aussi, à toi de voir. Bon codage ;-)

Sicryn
Messages : 11
Inscription : 23 Mai 2018 17:40

Re: [DB] Créer une action qui se répète à X temps.

Message par Sicryn » 10 Mai 2019 15:00

Hello !

Merci de votre aide ! J'ai réussi à résoudre mon problème en créant en event qui se déclenche au même moment que les jours repassent à 1 et que mois++ , c'était tout bête... :?

Merci de la rapidité! ( je repasserais peut etre poser de nouvelles questions bêtes un autre jour :-/ )

Bonne journée !

Répondre

Revenir vers « (C#) CSharp »