Skip to content

Instantly share code, notes, and snippets.

@FlaShG
Last active September 4, 2023 09:47
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save FlaShG/09b80bbc02a4bb6f9e2dda23ff9c5f8d to your computer and use it in GitHub Desktop.
Save FlaShG/09b80bbc02a4bb6f9e2dda23ff9c5f8d to your computer and use it in GitHub Desktop.
A replacement for Unity's MonoBehaviour.Invoke and MonoBehaviour.InvokeRepeating, with extra features.
using System;
using System.Collections;
using UnityEngine;
/// <summary>
/// Replaces MonoBehaviour.Invoke and MonoBehaviour.InvokeRepeating
/// with a more sophisticated attempt. Namely: No strings involved.
/// Use like this:
/// StartCoroutine(Invoker.Invoke(MyMethod, 2));
/// </summary>
public static class Invoker
{
private static readonly WaitForEndOfFrame waitForEndOfFrame = new WaitForEndOfFrame();
private static readonly WaitForFixedUpdate waitForFixedUpdate = new WaitForFixedUpdate();
public static IEnumerator Invoke(Action action, float delay)
{
return Invoke(action, delay, () => Time.deltaTime);
}
public static IEnumerator InvokeInRealtime(Action action, float delay)
{
return Invoke(action, delay, () => Time.unscaledDeltaTime);
}
private static IEnumerator Invoke(Action action, float delay, Func<float> deltaTime)
{
if (delay <= 0)
{
action();
yield break;
}
var countdown = delay;
while (countdown > 0)
{
yield return null;
countdown -= deltaTime();
}
action();
}
public static IEnumerator InvokeRepeating(Action action, float initialDelay, float delay)
{
return InvokeRepeating(action, initialDelay, delay, () => Time.deltaTime);
}
public static IEnumerator InvokeRepeatingInRealtime(Action action, float initialDelay, float delay)
{
return InvokeRepeating(action, initialDelay, delay, () => Time.unscaledDeltaTime);
}
private static IEnumerator InvokeRepeating(Action action, float initialDelay, float delay, Func<float> deltaTime)
{
if (initialDelay < 0 || delay <= 0) yield break;
var countdown = initialDelay;
if (countdown == 0)
{
countdown = delay;
action();
}
while (true)
{
yield return null;
countdown -= deltaTime();
while (countdown <= 0)
{
countdown += delay;
action();
}
}
}
public static IEnumerator InvokeNextFrame(Action action)
{
yield return null;
action();
}
public static IEnumerator InvokeNextFixedUpdate(Action action)
{
yield return waitForFixedUpdate;
action();
}
public static IEnumerator InvokeAtEndOfFrame(Action action)
{
yield return waitForEndOfFrame;
action();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment