Führen Sie eine Funktion zehn Sekunden lang aus und deaktivieren Sie sie zwei Sekunden lang

10

Ich habe eine bestimmte Funktion, die ich in der Update-Funktion aufrufe. Während der ersten zehn Sekunden sollte die Funktion in der Update-Funktion aufgerufen werden, dann sollte sie für die nächsten zwei Sekunden deaktiviert und dann für die nächsten zehn Sekunden erneut aktiviert werden. Dieser Zyklus sollte sich immer wieder wiederholen? Wie kann ich es ausführen?

MrRobot9
quelle

Antworten:

15

Alternativ gibt es einen Einzeiler mit Modul:

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
quelle
1
Gibt es einen Unterschied zwischen Repeat()und %(Modul)? In der Dokumentation heißt es: "Dies ähnelt dem Modulo-Operator, funktioniert jedoch mit Gleitkommazahlen." Der Modul funktioniert jedoch mit Gleitkommazahlen ...
BlueRaja - Danny Pflughoeft
1
@ BlueRaja-DannyPflughoeft ja und nein - soweit ich in verschiedenen Sprachen weiß, verhält sich der %Operator oft komisch - funktioniert entweder nicht mit Gleitkommazahlen, liefert unerwartete oder völlig falsche Ergebnisse für den Modulbetrieb in seiner mathematischen Bedeutung (was die Hardware-Natur von widerspiegelt die Operation auf ganzen Zahlen). Repeat()wurde nur als sicherere Option gewählt, um zu vermeiden, dass die genaue Implementierung des %Operators in C # / mono nachgeschlagen werden muss.
Wondra
3
Ich dachte, jede Sprache implementiert den IEEE 754-Standard, aber bis die "Modulo" -Definition des Standards nicht intuitiv ist , implementieren sie fast keine Sprachen.
BlueRaja - Danny Pflughoeft
Es wäre besser, wenn Sie den Kommentar über Code als einen anderen Codeblock implementieren und ihn entsprechend betiteln würden.
S. Tarık Çetin
6

Ich habe den folgenden Code nicht getestet, aber Sie werden auf die Idee kommen:

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
quelle
Das sollte nur funktionieren, wenn deltaTimees relativ kurz ist. Wenn das Delta länger als das ist, schlägt sleepDurationdies fehl.
James Curran
Wenn sleepDuration> Time.deltaTime ist, benötigen Sie ein solches System nicht.
Hellium
Angenommen, deltaTime beträgt 2,75 Sekunden. Sie haben 3 oder 4 "aktive" Anrufe und dann einen "Schlaf" -Anruf bis zur 50-Sekunden-Marke, wenn Sie 8 aktive Anrufe hintereinander haben sollten. In diesem Szenario kommt der erste Schlafanruf nach 11 Sekunden - Sie setzen die Zeit auf 0 zurück - er sollte auf 1 gesetzt werden.
James Curran
2
In Unity repräsentiert Time.deltaTime die verstrichene Zeit zwischen dem aktuellen Frame der Spiel-Engine und dem letzten Frame (daher hoffe ich für den Endbenutzer, dass Time.deltaTime niemals 2,75 Sekunden beträgt, ....). In diesem Zusammenhang können Sie einen Aufruf der Funktion oder einen "Nicht" -Aufruf der Funktion "verpassen", was meiner Meinung nach hier kein Problem darstellt.
Hellium
4

Sie können dies auch mit einer Coroutine tun. Etwas wie

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.
quelle