Exécutez une fonction pendant dix secondes et désactivez-la pendant deux secondes

10

J'ai une fonction particulière que j'appelle dans la fonction Update. Pendant les dix premières secondes, la fonction doit être appelée dans la fonction de mise à jour, puis elle doit être désactivée pendant les deux secondes suivantes, puis à nouveau l'activer pendant les dix secondes suivantes. Ce cycle devrait continuer à se répéter? Comment puis-je l'exécuter?

MrRobot9
la source

Réponses:

15

Alternativement, il existe un seul revêtement utilisant le module:

void Update()
{
    //if you want it loop from specific start time rather than from start of the game, 
    //subtract said time value from Time.time argument value
    if(Mathf.Repeat(Time.time, execDuration + sleepDuration) < execDuration)
        executeFunction();
}
Wondra
la source
1
Y a-t-il une différence entre Repeat()et %(module)? La documentation dit "c'est similaire à l'opérateur modulo mais cela fonctionne avec des nombres à virgule flottante" , mais le module fonctionne avec des flottants ...
BlueRaja - Danny Pflughoeft
1
@ BlueRaja-DannyPflughoeft oui et non - pour autant que je sache dans diverses langues, l' %opérateur agit souvent bizarrement - soit ne fonctionne pas avec des nombres à virgule flottante, donne des résultats inattendus ou carrément incorrects pour le fonctionnement du module dans sa signification mathématique (reflétant la nature matérielle de l'opération sur les entiers). Repeat()a été choisi comme une option plus sûre pour éviter d'avoir à rechercher l'implémentation exacte de l' %opérateur en C # / mono.
wondra
3
Je pensais que chaque langue implémentait la norme IEEE 754, mais TIL la définition "modulo" de la norme n'est pas intuitive, donc presque aucune langue ne l'implémente.
BlueRaja - Danny Pflughoeft
Il serait préférable que vous implémentiez le commentaire sur le code comme un autre bloc de code et que vous les intituliez en conséquence.
S. Tarık Çetin
6

Je n'ai pas testé le code suivant, mais vous aurez l'idée:

public float wakeUpDuration = 10.0f ;
public float sleepDuration = 2.0f;
private bool callFunction = true ;
private float time = 0 ;

void Update()
{
    time += Time.deltaTime;
    if( callFunction )
    {
         if( time >= wakeUpDuration )
         {
             callFunction = false;
             time = 0 ;
         }
         else
         {
             foo(); // Your function
         }
    }
    if( !callFunction && time >= sleepDuration )
    {
        callFunction = true;
        time = 0 ;
    }
}
Hellium
la source
Cela ne devrait fonctionner que s'il deltaTimeest relativement court. Si le delta est plus long, sleepDurationcela échouera.
James Curran
si sleepDuration> Time.deltaTime, alors, vous n'avez pas besoin d'un tel système.
Hellium
Non. Dites que deltaTime est de 2,75 secondes. Vous aurez 3 ou 4 appels "actifs" puis un appel "veille", jusqu'à la marque des 50 secondes, lorsque vous devriez avoir 8 appels actifs d'affilée. De plus, dans ce scénario, le premier appel de veille arrive à 11 secondes - vous remettez le temps à 0 - il devrait être réglé à 1.
James Curran
2
Dans Unity, Time.deltaTime représente le temps écoulé entre l'image actuelle du moteur de jeu et la dernière image (ainsi, j'espère pour l'utilisateur final que Time.deltaTime ne sera jamais de 2,75 secondes, ....). Dans ce contexte, vous pouvez "manquer" un appel à la fonction ou un appel "non" à la fonction, ce qui n'est pas un problème ici à mon humble avis.
Hellium
4

Vous pouvez également le faire avec une coroutine. Quelque chose comme

public class Comp : MonoBehaviour
{
  private bool _shouldCall;

  Start() 
  {
    StartCoroutine(UpdateShouldCall)
  }

  Update() 
  {
    if(_shouldCall)
        CallTheFunction();
  }

  IEnumerator UpdateShouldCall()
  {
    while(true) 
    {
        _shouldCall = true;
        yield return new WaitForSeconds(10);
        _shouldCall = false;
        yield return new WaitForSeconds(2);
    }
  }

}
Sava B.
la source