- Home /
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?
$$anonymous$$easure the time the operation takes with a StopWatch, then call yield WaitForSeconds with the difference between 1 second and the stopwatch's elapsed time.
Good idea. but i want to ensure that it runs good on all computers, since there might be machines who need more time for the coroutine's execution.
i can't just hard-code stuff which i might want others to use later
You're not hardcoding anything but the 1 second. You said you wanted the coroutine to return after exactly 1 second. $$anonymous$$y suggestion does that.
i need everything inside the coroutine done in one second no matter if the machine is faster than that.
like, if my machine does the complete coroutine in 200ms it needs to wait for 800 ms
I know. What I posted does that. Would you like a code sample?
Answer by CHPedersen · Jul 25, 2011 at 11:01 AM
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.
Javascript doesn't have a stopwatch from what it looks like. Also, i'm using unity free
JavaScript should have access to exactly the same as Unity's C# does, since they all compile to the same intermediate language and are all based on $$anonymous$$ono's .Net. System.Diagnostics.StopWatch is a standard .Net 2.0 component. It has nothing to do with Unity, so it doesn't matter that your version is the indie version.
@Christian H Pedersen
i'm getting a NullReferenceException when i try using the stopwatch :S
There is no telling what's going wrong when there's no code sample displaying what you've done. ;)
Initial guesses include attempting to call one of its methods without having instantiated it?
Answer by zeropoint · Jul 25, 2011 at 10:27 AM
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.
yield is not what i need for this..i need realtime waiting...
like the coroutine gets 1 second for its work
if coroutine finishes in 200 ms i want it to wait the other 800ms
Then why are you using a coroutine at all? They are not threads. If you don't yield, the coroutine will completely block the UI, input, repainting, progress bars, everything.
If that's actually what you want, then just use a normal function call (and the Stopwatch).
I doubt very much that is what you want.
Answer by zeropoint · Jul 25, 2011 at 10:56 AM
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.
Does this actually work?
I was under the impression Time.time does not change during an Update
?
I'm quite sure it doesn't. Time.time and Time.deltaTime are fixed for the entirety of Update and FixedUpdate, as they should be - you often want all Update functions to see the same values, and you need Time.time to always progress by the Time.deltaTime of the last Update.
Answer by aldonaletto · Jul 25, 2011 at 12:51 PM
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;
Your answer
Follow this Question
Related Questions
Increment X every one second. 2 Answers
Need help with this Rotation Script (fixes) 1 Answer
Finish One Combo 1 Answer
Realtime Clock? (needles) 1 Answer
Breathing sound effect using timers 1 Answer