Additional Functionality

There are two helper functions that are also included in the Timing object: CallDelayed and CallContinously.

  • CallDelayed calls the specified action after some number of seconds.
  • CallContinously calls the action every frame for some number of seconds.

Both of these could easily be created using coroutines, but this basic functionality ends up being used so often that we’ve included it in the base module.

// This will start the _RunFor5Seconds coroutine, 2 seconds from now.
Timing.CallDelayed(2f, delegate { Timing.RunCoroutine(_RunFor5Seconds(handle)); });

// This does the same thing, but without creating a closure. (A closure creates a GC alloc.)
//  "handle" is being passed in to CallDelayed and CallDelayed passes 
//  it back to RunCoroutine as the variable "x".
Timing.CallDelayed<IEnumerator<float>>(handle, 2f, x => { Timing.RunCoroutine(_RunFor5Seconds(x)); });
private void PushOnGameObject(Vector3 amount)
{
    transform.position += amount * Time.deltaTime;
}

// This will push this object forward one world unit per second for 4 seconds.
Timing.CallContinuously(4f, delegate { PushOnGameObject(Vector3.forward); }, Segment.FixedUpdate);

// CallContinously also has a non-closure version. It's extra important to try
//  not to make closures on CallContinously, since it will result in a GC alloc every frame.
Timing.CallContinuously<Vector3>
    (Vector3.forward, 4f, vector => PushOnGameObject(vector), Segment.FixedUpdate);

// This line is equalivant to the previous line:
Timing.CallContinuously(Vector3.forward, 4f, PushOnGameObject, Segment.FixedUpdate);

 
CallContinously can be used to create simple coroutine-like behavior without needing to use the yield return pattern.. if you’re into that sort of thing.


By default MEC prints any exceptions out to the console and quits the coroutine that threw the exception. However, if you want to do something different with exceptions then you can define your own custom error receiver:

Timing.Instance.OnError = OnError;

private void OnError(Exception exception)
{
    Debug.LogError("The exception was seen: " + exception.Message);
}

 
If you decide to run with more than one Timing instance then you can define different error handlers for different instances.

FYI: You’ll save yourself some trouble if you never point the OnError function to a lambda expression, since lambda expressions break their links whenever the Unity debugger recompiles.. and you’re much better off if your error handling code is solid. Instead of a lambda, use a function that is defined in one of your classes.