Wykonaj funkcję na dziesięć sekund i wyłącz ją na dwie sekundy

10

Mam określoną funkcję, którą wywołuję w funkcji aktualizacji. Przez pierwsze dziesięć sekund funkcja powinna zostać wywołana w funkcji aktualizacji, następnie powinna zostać wyłączona na kolejne dwie sekundy, a następnie ponownie włączyć ją na kolejne dziesięć sekund. Ten cykl powinien się powtarzać? Jak mogę to wykonać?

MrRobot9
źródło

Odpowiedzi:

15

Alternatywnie istnieje moduł jednowarstwowy wykorzystujący moduł:

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
źródło
1
Czy istnieje różnica między Repeat()i %(modułem)? Dokumentacja mówi „jest podobny do operatora modulo, ale działa z liczbami zmiennoprzecinkowymi” , ale moduł działa z liczbami zmiennoprzecinkowymi ...
BlueRaja - Danny Pflughoeft
1
@ BlueRaja-DannyPflughoeft tak i nie - o ile wiem w różnych językach, %operator często działa dziwnie - albo nie działa z liczbami zmiennoprzecinkowymi, daje nieoczekiwane lub wręcz niepoprawne wyniki operacji modułu w znaczeniu matematycznym (odzwierciedlając charakter sprzętowy operacja na liczbach całkowitych). Repeat()został wybrany jako bezpieczniejsza opcja, aby uniknąć konieczności sprawdzania dokładnej implementacji %operatora w C # / mono.
wondra,
3
Myślałem, że każdy język implementuje standard IEEE 754, ale TIL definicja „modulo” jest nieintuicyjna, więc prawie żaden język jej nie implementuje.
BlueRaja - Danny Pflughoeft
Byłoby lepiej, gdybyś zaimplementował komentarz do kodu jako kolejny blok kodu i odpowiednio go nazwał.
S. Tarık Çetin
6

Nie testowałem następującego kodu, ale wpadniesz na pomysł:

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 ;
    }
}
Hel
źródło
To powinno działać tylko wtedy, gdy deltaTimejest stosunkowo krótkie. Jeśli delta jest dłuższa niż sleepDurationto, to się nie powiedzie.
James Curran
jeśli sleepDuration> Time.deltaTime, to nie potrzebujesz takiego systemu.
Hellium
Nie. Powiedz, że deltaTime wynosi 2,75 sekundy. Będziesz mieć 3 lub 4 „aktywne” połączenia, a następnie jedno „uśpienie”, aż do 50 sekund, kiedy powinieneś mieć 8 aktywnych połączeń z rzędu. Również w tym scenariuszu pierwsze połączenie uśpione przychodzi o 11 sekundach - resetujesz czas na 0 - powinno być ustawione na 1.
James Curran
2
W Unity Time.deltaTime reprezentuje czas, który upłynął między bieżącą klatką silnika gry a ostatnią klatką (dlatego mam nadzieję, że dla końcowego użytkownika Time.deltaTime nigdy nie będzie 2,75 sekundy, ....). W tym kontekście możesz „przegapić” wywołanie funkcji lub „nie” wywołanie funkcji, co nie jest tutaj problemem IMHO.
Hellium
4

Możesz to zrobić również z korupcją. Coś jak

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.
źródło