- Home /
What is the most CPU efficient and smooth way to create timed events?
For my game, I need to move gameObjects and trigger sounds (audio.Play()) at set intervals that can get very fast depending on the level of the game (<1000ms).
So far, I have tried 3 timing methods. Firstly yield / StartCoroutine with WaitForSeconds:
IEnumerator SendTimerNotification()
{
while(true)
{
NotificationCenter.defaultCenter.postNotification(_soundBeatEvent);
yield return new WaitForSeconds(_bpmInMilliseconds); // <- 0.115f
}
}
secondly as above with WaitForFixedUpdate:-
IEnumerator SendTimerNotificationFixed()
{
float curTime = Time.time;
while (true)
{
if (Time.time >= curTime + _bpmInMilliseconds)
{
NotificationCenter.defaultCenter.postNotification(_soundBeatEvent);
curTime += _bpmInMilliseconds;
}
yield return new WaitForFixedUpdate();
}
}
and finally, InvokeRepeating:
InvokeRepeating("SendTimerNotification", 0, _bpmInMilliseconds);
With all instances, once the speed is less than a second, the cpu usage gets quite high. For the sake of brevity, the NotificationCenter class shown is a simple class that broadcasts notifications. Currently there is one gameObject listening for this notification and it plays its attached audioSource object when it is received.
Are there other more cpu efficient means of handling timed events in Unity that I have yet to discover (I have been trialing the package a week).
Any info on the subject is most appreciated.
Thanks,
Dave
Best thing is to run the profiler and see; I suspect there is no significant difference, and that 99.9% of CPU usage is due to whatever code is running at set intervals.
Hey Eric. I think there is a lot of truth in this. Ironically WaitForSeconds seems a bit smoother than WaitForFixedUpdate which audibly falters quite a bit if I move the mouse etc
Answer by zannghast · Oct 28, 2010 at 01:17 AM
Hey there boymeetsrobot!
Have you tried putting the countdown/set interval inside the Update function? Instead of putting it inside an infinite loop, that is. I mean, if there wasn't a special requirement to use the while(true) technique hehe.
Update runs every frame; the point is not to run every frame, but at particular intervals.
I see your point, but what I meant was to actually put the set interval inside the Update function. That way, you could do without the infinite loop (which could possible be adding to cpu usage). Take for example case # 2: Why not experiment with putting a if(Time.time > polledTime) { send notifiction; update polledTime } inside the Update function? That won't necessarily mean the notification is sent every frame, but, only when Time.time exceeds the polledTime.
Dendro.. hi where all the people go?:)) Can u help me with my questions because i didnt received no answer for 2 days or 3...please
Thanks for your response. The Update loop is no different really. The infinite condition in the while loop was just to illustrate the example. I am using a bool to stop it in my code.
Answer by dissidently · Mar 12, 2011 at 05:28 AM
this is going to sound weird. but stay with me. it's something I've been developing for a couple things I'm working on in terms of an animated UI. And it seems to be efficient, certainly has been for the prototypes I've built so far. Learnt this trick from UDK.
Somewhere off scene, away from the camera, setup a physics rig with an object that has mass, a rigid body and collider. Setup a plane to catch it when it falls or is thrown, also with collider. Place a collision detection script on the object that sends notification to wherever you gameplay is going on that needs timing info.
What you're trying to do is setup a rig that acts as your clock. on releasing a held physics object, or applying force to it in the direction of the target collider plane, it's not requiring anything of you until it hits. At which point some code attached to either the plane of the falling object let's you know that "timer event" has occurred.
Now figure out, with current gravity in your scene, how long it takes for an object to fall from the position you place it to the collidor plane that stops it at the bottom. You probably want/need setup a timer that times this occurrence so you can get it accurate, then it's a combination of trial and error and your maths ability to get the right timings.
// Note gravity can be changed in Unity, to any direction, and any force, fun and useful
This may all seem illogical at first, until you consider this... you can have dozens of these boxes falling/thrown at the collidor at different rates/mass/heights to generate all the timing events you can imagine. And it's relatively cheap processing for complex timings.
Then you can feed out info on rates(forces) and heights to the objects over and over again to set more timing events, and forget about them until they hit the ground plane to let you know again.
Keep in mind the physics system is not perfect. If your objects are moving to fast they might go straight through the plane without detection. So try keep them low to the plane rather than add huge forces to get short times.
That's far more CPU-intensive, complicated, and error-prone than just using a simple coroutine or Invoke, and therefore I'd highly discourage it, sorry. Even using manual timers in Update would be a lot better.
it's not meant for simple situations. it's meant for doing dozens of concurrent ti$$anonymous$$gs. You got a better way of doing dozens of concurrent ti$$anonymous$$gs? I'm all ears!
Yes, coroutines would be better, or Invoke. Aside from using using a lot more CPU time doing pointless physics calculations when you just want a timer, the physics engine isn't even 100% deter$$anonymous$$istic.
there's a caveat to this for me. I'm using the falling blocks as both times and revealers. they reveal hidden UI elements as they fall, at the same rate I want them shown. But you've got me fascinated... to see if there's another way to do this. I'll don't understand coroutines well enough to do dozens of them nested all over the place. And Invoke means nothing to me. But most fascinating, the word "deter$$anonymous$$istic". Got no idea what that means in this context. Got a unity reference page that explains all these? ;)
Yes, the docs explain coroutines and Invoke. You can look them up by using the search feature. An internet search on "physics engine deter$$anonymous$$istic" will show many relevant pages.
Your answer
Follow this Question
Related Questions
Increase/Decrease Value With Time - Problem 4 Answers
Waitforseconds vs Time 2 Answers
continuous shooting 1 Answer
yield WaitForSeconds 1 Answer