[RESOLU] utilisations successives de InvokeRepeating()

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
Avatar de l’utilisateur
Kaloverian
Messages : 166
Inscription : 10 Août 2016 03:03

[RESOLU] utilisations successives de InvokeRepeating()

Message par Kaloverian » 16 Déc 2020 23:36

bonjour,

Mon but est en fonction des bornes d'intervalles,je fasse répéter différentes fonctions.
Voici ce code au plus simple illustrant ceci mais il ne fonctionne pas.Pourquoi?

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class draw_by_parts : MonoBehaviour
{
	public float retard_initial,intervalle_de_temps;
	int i=0;
	int k=0;

	public float a,b;

	// Use this for initialization
	void Start()
	{
		draw_letter_A();
	}
	
	void Spawn_part_one()
	{
		i++;
		print("valeur de I: "+i);
	}

	void Spawn_part_two()
	{
		k++;
		print("valeur de K: "+k);

	}

	void draw_letter_A ()
	{
		if((Time.time>=0) && (Time.time<=a))
		{ 
			InvokeRepeating("Spawn_part_one", retard_initial, intervalle_de_temps);
		}

		if((Time.time>=a) && (Time.time<=b))
		{	
			CancelInvoke ("Spawn_part_one");
			InvokeRepeating("Spawn_part_two", retard_initial, intervalle_de_temps);
		}

		if(Time.time>=b)
		{
			CancelInvoke ("Spawn_part_two");
		}
	}
}
seul Spawn_part_one() est appelée mais jamais Spawn_part_two().
Où est l'erreur?

merci de votre aide

Avatar de l’utilisateur
jmhoubre
Messages : 340
Inscription : 05 Oct 2019 22:05

Re: utilisations successives de InvokeRepeating()

Message par jmhoubre » 17 Déc 2020 06:20

Dans ton esprit, c'est quoi la fonction Start () ?

Avatar de l’utilisateur
Kaloverian
Messages : 166
Inscription : 10 Août 2016 03:03

Re: utilisations successives de InvokeRepeating()

Message par Kaloverian » 18 Déc 2020 14:04

Les InvokeRepeating que j'ai aperçus sur internet se trouvent dans la fonction Start()
cf :
https://docs.unity3d.com/ScriptReferenc ... ating.html


Faut-il que je sorte de Start() l'appel de la fonction draw_by_parts pour que ça fonctionne?
Je ne ferai certainement pas cet appel dans la fonction Update.
Alors j'effectue cet appel dans quelle fonction?

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 5542
Inscription : 28 Avr 2014 11:57
Localisation : Toulouse

Re: utilisations successives de InvokeRepeating()

Message par boubouk50 » 18 Déc 2020 15:00

Ce n'est pas la question posée.

Tu as un processus de méthodes Monobehaviour (behaviour = comportement) qui est est immuable:
Awake () -> Start () -> Update () -> LateUpdate () -> Goto Update () at next frame.

Le Start () n'est joué qu'une seule et unique fois à l'activation du Component.
Ici, tu appelles draw_letter_A() dans le Start () donc une seule fois au début.
Ensuite, tu répètes soit Spawn_part_one soit Spawn_part_two, mais jamais tu ne reviens dans draw_letter_A() pour ton test, donc seule l'une des deux est appelée (et donc toujours la même).

Il te faut donc répéter le test. Il te faut donc répéter draw_letter_A() depuis le Start (), comme dans l'exemple que tu donnes en fait, et que tu n'as pas suivi.
"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

Avatar de l’utilisateur
Kaloverian
Messages : 166
Inscription : 10 Août 2016 03:03

Re: utilisations successives de InvokeRepeating()

Message par Kaloverian » 18 Déc 2020 16:19

Même avec ce code,cela ne fonctionne pas:

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

// n'affiche rien dans la console

public class draw_by_parts2 : MonoBehaviour {


	public float retard_initial,intervalle_de_temps;
	int i=0;
	int k=0;

	public float a,b;





	void Start(){


		draw_letter_A ();

		StartCoroutine (waiter());
		draw_letter_A ();



	}

	IEnumerator waiter(){

		yield return new WaitForSecondsRealtime(a);}

	// Use this for initialization
	void Spawn_part_one() {



		i++;
		print("valeur de I: "+i);
	}



	void Spawn_part_two() {


		k++;
		print("valeur de K: "+k);

	}


	void draw_letter_A ()
	{


		if((Time.time>=0) && (Time.time<=a))
		{ 
			InvokeRepeating("Spawn_part_one", retard_initial, intervalle_de_temps);
		}



		if((Time.time>=a) && (Time.time<=b))
		{	
			CancelInvoke ("Spawn_part_one");
			InvokeRepeating("Spawn_part_two", retard_initial, intervalle_de_temps);
		}

		if(Time.time>=b)
		{CancelInvoke ("Spawn_part_two"); }
	}



	//float draw_letter_A(float m);




	// Update is called once per frame
	void Update () {

		//draw_letter_A();

		//print ("temps écoulé: " + Time.time);


		//}
	}


}



Avatar de l’utilisateur
Max
Messages : 8144
Inscription : 30 Juil 2011 13:57
Contact :

Re: utilisations successives de InvokeRepeating()

Message par Max » 18 Déc 2020 18:49

Bonsoir,

dans ton code:

Code : Tout sélectionner

	void Start(){
		draw_letter_A ();
		StartCoroutine (waiter());
		draw_letter_A ();
	}

	IEnumerator waiter(){
		yield return new WaitForSecondsRealtime(a);}
ta coroutine ne sert à rien. Je pense que dans ton espris cela équivaux à une tempo, ce qui n'est pas le cas.
Donc tu exécutes deux fois draw_letter_A (); à la suite sans temporisation.
Au pire, si tu souhaites une phase d'attente entre les deux, il faudrait écrire:

Code : Tout sélectionner

	void Start(){
		draw_letter_A ();
		StartCoroutine (waiter());
	}

	IEnumerator waiter(){
		yield return new WaitForSecondsRealtime(a);
			draw_letter_A ();
		}
même si j'ai du mal à vraiment appréhender le principe de ce que tu cherches à faire avec ton script, qui me semble assez confus.
Image
Pas d'aide par MP, le forum est là pour ça.
En cas de doute sur les bonnes pratiques à adopter sur le forum, consulter la Charte et sa FAQ

Avatar de l’utilisateur
Kaloverian
Messages : 166
Inscription : 10 Août 2016 03:03

Re: utilisations successives de InvokeRepeating()

Message par Kaloverian » 18 Déc 2020 19:17

Voici mon code corrigé qui fonctionne:

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;



public class draw_by_parts2 : MonoBehaviour {


	public float retard_initial,intervalle_de_temps;
	int i=0;
	int k=0;

	public float a,b;






	IEnumerator waiter(){

		yield return new WaitForSecondsRealtime(a);
		
		CancelInvoke ("Spawn_part_one");
		InvokeRepeating("Spawn_part_two", retard_initial, intervalle_de_temps);

		yield return new WaitForSecondsRealtime(b);
		CancelInvoke ("Spawn_part_two");
	}

	// Use this for initialization
	void Spawn_part_one() {



		i++;
		print("valeur de I: "+i);
	}



	void Spawn_part_two() {


		k++;
		print("valeur de K: "+k);

	}




	void Start(){


		
		InvokeRepeating("Spawn_part_one", retard_initial, intervalle_de_temps);

		StartCoroutine (waiter());




	}


	




	// Update is called once per frame
	void Update () {

	}


}



Avatar de l’utilisateur
jmhoubre
Messages : 340
Inscription : 05 Oct 2019 22:05

Re: [RESOLU] utilisations successives de InvokeRepeating()

Message par jmhoubre » 18 Déc 2020 22:13

Bonsoir,

parfait s'il fonctionne.

Juste une remarque : quand je lis ton code, j'ai énormément de lignes blanches inutiles. Comme la fenêtre de visualisation du code a une hauteur insuffisante, c'est assez fastidieux à lire avec de fréquents recours à l'ascenseur vertical et l'absence de vision d'une partie suffisante du code. Je ne sais pas si je suis le seul à être embêté avec ceci, mais si tu pouvais faire un effort pour nettoyer ton code avant de le publier, cela faciliterait la vie de ceux qui pourraient t'aider.

Si j'ai compris ce que tu veux faire :
- entre 0 et a secondes, répéter Spawn_part_one;
- entre A et b secondes, répéter Spawn_part_two;
- après b secondes, ne plus rien répéter.
C'est cela ?

Quelques conseils pour améliorer la lisibilité :
- Update ne faisant rien, supprime-la.
- Met les fonctions intégrées d'Unity en tête de classe (Start Update OnTrigger OnCollision...)
- Tes variables devraient avoir un nom signifiant. Il est admis que le compteur d'une boucle for soit nommé i, mais pour a et b, des noms comme borneInferieure et borneSuperieure seraient plus lisibles. D'autant que tu le fais pour retard_initial et intervalle de temps.
- Utilise les conventions les plus communes pour le nommage : PascalCase pour les classes, les fonctions et les propriétés, camelCase pour les variables, et évite le français :
** class draw_by_parts2 -> class DrawByParts2
** retard_initial -> retardInitial -> initialDelay
** intervalle_de_temps -> intervalleDeTemps -> timeInterval
** IEnumerator waiter() -> IEnumerator Waiter()
** Spawn_part_one -> SpawnPartOne ...

Avatar de l’utilisateur
boubouk50
ModoGenereux
ModoGenereux
Messages : 5542
Inscription : 28 Avr 2014 11:57
Localisation : Toulouse

Re: utilisations successives de InvokeRepeating()

Message par boubouk50 » 19 Déc 2020 18:21

Kaloverian a écrit :
18 Déc 2020 19:17
Voici mon code corrigé qui fonctionne:

Code : Tout sélectionner

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class draw_by_parts2 : MonoBehaviour {
	public float retard_initial,intervalle_de_temps;
	int i=0;
	int k=0;

	public float a,b;
	IEnumerator waiter(){

		yield return new WaitForSecondsRealtime(a);
		
		CancelInvoke ("Spawn_part_one");
		InvokeRepeating("Spawn_part_two", retard_initial, intervalle_de_temps);

		yield return new WaitForSecondsRealtime(b);
		CancelInvoke ("Spawn_part_two");
	}

	// Use this for initialization
	void Spawn_part_one() {
		i++;
		print("valeur de I: "+i);
	}

	void Spawn_part_two() {
		k++;
		print("valeur de K: "+k);
	}

	void Start(){
		InvokeRepeating("Spawn_part_one", retard_initial, intervalle_de_temps);
		StartCoroutine (waiter());
	}
}
C'est un peu un patchwork qui finit par fonctionner.
Tu peux avoir des problèmes avec ce code, notamment si retard_initial est supérieur à a.
Ensuite, dans la même veine, tu attends a pour lancer Spawn_part_two, mais tu retardes son lancement de retard_initial. Là encore, b peut donc être atteint avant que la répétition n'intervienne.
a et b devrait donc être calculés en fonction de retard_initial pour qu'ils soient forcément supérieurs.
InvokeRepeating permet de gérer une fonction par une coroutine masquée, ici, appelé dans une coroutine, c'est redondant, même si ce n'est pas faux, mais un peu lourd.
"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 »