Выполнить функцию на десять секунд и отключить ее на две секунды

10

У меня есть особая функция, которую я вызываю в функции обновления. В течение первых десяти секунд функция должна вызываться в функции обновления, затем она должна быть отключена на следующие две секунды, затем снова включить ее на следующие десять секунд. Этот цикл должен повторяться? Как я могу выполнить это?

MrRobot9
источник

Ответы:

15

В качестве альтернативы, есть модуль с одним вкладышем:

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
источник
1
Есть ли разница между Repeat()и %(модуль)? Документация гласит: «Это похоже на оператор по модулю, но оно работает с числами с плавающей запятой» , но модуль работает с числами с плавающей запятой ...
BlueRaja - Дэнни Пфлугхофт
1
@ BlueRaja-DannyPflughoeft да и нет - насколько я знаю, на разных языках %оператор часто ведет себя странно - либо не работает с числами с плавающей запятой, либо дает неожиданные или совершенно неверные результаты для работы модуля в математическом смысле (отражая аппаратную природу операция над целыми числами). Repeat()был выбран просто как более безопасный вариант, чтобы избежать необходимости искать точную реализацию %оператора в C # / mono.
Wondra
3
Я думал, что каждый язык реализует стандарт IEEE 754, но TIL определение «по модулю» стандарта не является интуитивно понятным, поэтому почти ни один язык не реализует его.
BlueRaja - Дэнни Пфлюгофт
Было бы лучше, если бы вы реализовали комментарий над кодом как другой блок кода и назвали его соответствующим образом.
С. Тарык Четин
6

Я не тестировал следующий код, но вы получите идею:

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
источник
Это должно работать, только если deltaTimeоно относительно короткое. Если дельта длиннее, чем sleepDurationэто, это не удастся.
Джеймс Керран
если sleepDuration> Time.deltaTime, то вам не нужна такая система.
Hellium
Скажем, deltaTime составляет 2,75 секунды. У вас будет 3 или 4 «активных» вызова, затем один «спящий» вызов, до отметки 50 секунд, когда у вас должно быть 8 активных вызовов подряд. Кроме того, в этом сценарии первый спящий вызов происходит через 11 секунд - вы сбрасываете время на 0 - оно должно быть установлено на 1.
Джеймс Керран
2
В Unity Time.deltaTime представляет истекшее время между текущим кадром игрового движка и последним кадром (таким образом, я надеюсь, что для конечного пользователя Time.deltaTime никогда не будет 2,75 секунды, ....). В этом контексте вы можете «пропустить» вызов функции или «не» вызов функции, что здесь не является проблемой ИМХО.
Hellium
4

Вы можете сделать это с сопрограммой также. Что-то вроде

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);
    }
  }

}
Сава Б.
источник