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

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.

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.