Keeping track of time?

The thing is, i want to give my coroutine EXACTLY one second to perform all it’s actions, and (because some computers are faster than other) wait for this second to complete even if the coroutine finishes in 200 ms…

any advice on how this is done?

Try something like this:

System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch();

IEnumerator SomeCoroutine()
{
    stopwatch.Start();

    // Do operations

    stopwatch.Stop();
    float timeTaken = 0.001f * stopwatch.ElapsedMilliseconds;
    stopwatch.Reset();
    // Wait for 1 second, minus the amount of time that the operations were measured to take:
    yield return new WaitForSeconds(1 - timeTaken);
}

You might have to take a second to translate it to javascript, of course, but that’s the general idea.

How are you exactly counting 1s?

This does work:

// Prints 0
print (Time.time);
// Waits 5 seconds
yield WaitForSeconds (5);
// Prints 5.0
print (Time.time);

It’s from documentation.

I don’t think we have directly such method to achieve that but you can surely go for polling

void YourCoroutine(float waitTime){
  float localTime = Time.time; // store the entry point time

  // your stuff
  // goes here
  // ...

  // check whether required time has elapsed
  while(Time.time - localTime < waitTime)
    ; // do nothing -- just wait for your time to elapse
}

Note that this waiting time doesn’t consider the time elapsed in calling and returning from the YourCoroutine method. If you need to take care of that too then take the line float localTime = Time.time; just before calling YourCoroutine and the while loop after calling it.

You can set the endTime at beginning, and let the routine check it before returning:

function OneSecondRoutine(){
  var endTime = Time.time + 1;
  // do your stuff here
  // wait endTime to finish:
  while (Time.time < endTime){
    yield;  // the routine will check endTime each frame
  }
}

Notice that:

1- You must use yield to free Unity while your routine waits, or your FPS will drop below 1 frame per second;

2- If you call this routine again before it has ended, it will start a new coroutine running in parallel to the first one. To avoid this, you must use a public busy boolean variable defined outside any function:

  • only call OneSecondRoutine if busy is false;

  • set busy to true at the beginning of OneSecondRoutine;

  • set busy to false at the end of OneSecondRoutine;