Probleme avec CancelInvoke().

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 : 336
Inscription : 10 Août 2016 03:03

Probleme avec CancelInvoke().

Message par Kaloverian » 19 Jan 2022 16:03

bonjour,

Voici un petit script simple dont la condition incluant CancelInvoke() ne fonctionne pas.
Dès que l'incrémentation est supérieure à 5,InvokeRepeating doit s'arreter mais ne s'arrete pas !
Pourquoi?

Code : Tout sélectionner

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



public class appui_particulier : MonoBehaviour
{ 
    
    int c=0;

   public float time_interval;
   public int incrementation;
    
    // Start is called before the first frame update
    void Start()
    {
         
    }

  // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.N))
        {
        
        InvokeRepeating("increment",0,time_interval);
      
         if(increment()>5)
         {
          CancelInvoke(); 
         }
          
        }
         
    }

  int increment()
  {
      
      c+=incrementation;
      print("valeur incrémentée: "+c);
      return c;
  }
}

Quand j'écris ce script:

Code : Tout sélectionner

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



public class appui_particulier : MonoBehaviour
{ 
    
    int c=0;

   public float time_interval;
   public int incrementation;
    
    // Start is called before the first frame update
    void Start()
    {
         
    }

  // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.N))
        {
        
        InvokeRepeating("increment",0,time_interval);
      
        CancelInvoke(); 
         
          
        }
         
    }

  int increment()
  {
      
      c+=incrementation;
      print("valeur incrémentée: "+c);
      return c;
  }
}

InvokeRepeating ne s'établit jamais donc CancelInvoke() agit bien alors que dans le script précédent,CancelInvoke() n'agit pas.

merci de votre aide
Dernière édition par Kaloverian le 19 Jan 2022 16:48, édité 1 fois.

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

Re: pourquoi

Message par boubouk50 » 19 Jan 2022 16:21

Ce "simple" code est assez brouillon.

Factuellement, ce que tu fais:
A chaque appui sur la touche N, tu lances une nouvelle itération d'InvokeRepeating () puis tu testes l'incrément pour tout couper.
Donc tu vas répéter la répétition à chaque appui, déjà. Est-ce voulu? Soit.
Ensuite, tu ne vas tester l'incrément seulement à l'appui de la touche N. Dans ce cas, si tu n'appuies pas sur N après que l'incrément soit passé à 5, tu n'arrêtes rien.
Aussi, tu exécutes InvokeRepeating directement avant de le couper, donc tu auras au moins une itération lors d'un appui sur N quel que soit la valeur de l'incrément.
Et enfin, incrementation n'est pas défini (tu as donc sciemment coupé du code) et on ne connait pas la valeur de time_interval. Là aussi, ça pourrait ajouter de la confusion au code en plus du manque évident de logique.

Bref, revois la logique de ton code, CancelInvoke ()n'y est pour rien dans le résultat.
"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 : 336
Inscription : 10 Août 2016 03:03

Re: pourquoi

Message par Kaloverian » 19 Jan 2022 16:49

Et enfin, incrementation n'est pas défini (tu as donc sciemment coupé du code) et on ne connait pas la valeur de time_interval. Là aussi, ça pourrait ajouter de la confusion au code en plus du manque évident de logique.
scripts corrigés malgré les erreurs bien citées et encore existantes

Mais ce script ne fonctionne toujuors pas:

Code : Tout sélectionner

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



public class appui_particulier : MonoBehaviour
{ 
    
    int c=0;

   public float time_interval;
   public int incrementation;
    
    // Start is called before the first frame update
    void Start()
    {
         
    }

  // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.N))
        {
        
        InvokeRepeating("increment",0,time_interval);
    
       }
        
          
      if(increment()>5)
         {
          CancelInvoke(); 
        }
         
    }

  int increment()
  {
      
      c+=incrementation;
      print("valeur incrémentée: "+c);
      return c;
  }
}

Je n'y arrive pas...

Là j'y suis arrivé:

Code : Tout sélectionner

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

//à chaque appui court d'une touche,ça incrémente par exemple de 1 tous les dizièmes de secondes
//code non OK

public class appui_particulier : MonoBehaviour
{ 
    
 

    int c=0;

    public int incrementation,nb_increment;
    public float time_interval;
    
    // Start is called before the first frame update
    void Start()
    {
     
    }

 


    // Update is called once per frame
    void Update()
    {
        if(Input.GetKeyDown(KeyCode.N))
        {
     
        InvokeRepeating("increment",0,time_interval);//atention:ne pas mettre d'argument dans la fonction increment sinon InvokeRepeating ne peut être appelé !
      
      
      
          
        }

        
      if(c>=5)
       {
        CancelInvoke(); 
        c=0;
       }
         
    }

  int  increment()
  {
      
      c+=incrementation;
      print("valeur incrémentée: "+c);
    
      return c;
  }
}


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

Re: pourquoi

Message par boubouk50 » 19 Jan 2022 17:27

Que vaut incrementation? 1 j'espère.
Que vaut time_interval?

C'est de pire en pire... Ici une fois l'incrément passé 5, tu l'appelles continuellement! Du coup, ce n'est pas InvokeRepeating () qui l'appelle mais ta condition.

Et il faut arrêter de tout fourrer dans l'Update ()! Ce n'est pas une fonction magique! Il doit être utilisé UNIQUEMENT pour les tests continus.

Code : Tout sélectionner

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

public class appui_particulier : MonoBehaviour
{ 
    int c=0;

   public float time_interval;
   public int incrementation;
  
  // Update is called once per frame
    void Update()
    {
    	// A chaque appui sur la touche N
        if(Input.GetKeyDown(KeyCode.N))
        {
        	// Si l'incrément est inférieur ou égal à 5 alors je lance une répétition (tu es bien sur que c'est ce que tu veux? ça ne semble pas du tout logique)
        	if (c <= 5)
        		InvokeRepeating("increment", 0, time_interval);
	}
    }

  void increment()
  {
  	//Incrémente c
      c+=incrementation;
      // Affiche la valeur en console
      print("valeur incrémentée: "+c);
      // si la valeur est dépassée, arrêter les invocations
      if (c > 5)
      	CancelInvoke(); 
  }
}
Depuis le temps que tu codes, au vu du niveau acquis, je doute que tu aies suivi quelconque cours de programmation. Si c'est le cas, je t'invite à en suivre plusieurs pour bien comprendre et acquérir la logique associée à Unity. Si tu as suivi des cours, ben je ne sais pas quoi te dire, mais je ne vois aucune progression depuis les années à te suivre sur ce forum et je ne sais pas comment t'aider à t'améliorer.
Ce n'est pas pour être méchant, notre but est aussi d'aider nos membres à s'améliorer au fil du temps, et je ne sais comment t'aider à y parvenir.
"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

Xann_71
Messages : 93
Inscription : 23 Juin 2015 22:25
Localisation : Le puy en velay

Re: Probleme avec CancelInvoke().

Message par Xann_71 » 14 Fév 2022 18:12

Bonjour.
Pour commencer, je n'ai pas un niveau suffisamment avancé pour me permettre de dire ce qui est bien ou pas dans un code mais j'ai également été surpris de voir une fonction InvokeRepeating() dans une fonction update (qui se répète elle même à chaque frame). Peut être faut il revoir la structure sous un autre angle.

Ensuite, pour ton problème d'invokcancel():
Pour ce que l'on voit dans ton code, InvokCancel() ne sera exécutée que si et seulement si "c" est supérieur à 5. or rien n'indique dans ton code que c puisse passer à 5.
c est initialisée à 0 lorsque tu la déclare puis elle est incrémentée de la valeur de la valeur de la variable "incrementation" dans ta fonction increment(). Mais à aucun moment la valeur de ta variable "incrémentation" n'est renseignée. Tu la déclare en début de script sans lui donner de valeur, et en relisant plusieurs fois ton code, je ne vois aucun moment ou tu renseigne sa valeur. Dans le meilleur des cas, sa valeur reste 0 et donc ta condition if(c >5) ne sera jamais remplie puisque "c" restera à 0. Dans le pire des cas (et là je risque de ne pas être clair car je comprend l'idée de ce que je vais expliquer mais je ne sais pas trop comment le faire comprendre) l'espace alloué à ta variable "incrementation" avait déjà une valeur (int ou autre) et ton script va soit se court-circuité, soit renvoyer une erreur d'incompatibilité.

Ce que tu peux essayer de commencer à faire, c'est d'ajouter des print de tes variables "c" et "incrementation" à différents endroits du code pour voir comment elles évoluent lors de l'exécution du programme. En parallèle, définit une valeur dans ton code pour "incrementation". Ou encore plus simple, si "incrementation" est égale à 1, remplace ta ligne "c+=incrementation;" par "c++;", cela aura pour effet d'ajouter 1 à c à chaque passage dans la fonction increment().

J'espère que m'a réponse pourra t'aider.

Répondre

Revenir vers « (C#) CSharp »