Search code examples
c#unity-game-enginedelayinvoke

C# Custom Invoke method to invoke various other methods


I have various methods that work fine, but I want to call them only after a delay. To avoid writing a different method for all of them I figured it's more beneficial to Invoke them somehow. I made the methods so that they exclude Unity's timeScale, so they always wait for Real seconds, using a custom built short function.

The WaitForRealSeconds:

public class WaitForRealSecondsClass
{
    #region Wait for real seconds

    public Coroutine WaitForRealSeconds(float aTime, MonoBehaviour mono)
    {
        return mono.StartCoroutine(_WaitForRealSeconds(aTime));
    }
    private IEnumerator _WaitForRealSeconds(float aTime)
    {
        while (aTime > 0.0f)
        {
            aTime -= Mathf.Clamp(Time.unscaledDeltaTime, 0, 0.2f);
            yield return null;
        }
    }
    #endregion
}

The way I wish to Invoke a Move function of mine:

public void InvokeAnim(float timeBeforeStart, Action<MonoBehaviour> MoveFunction, MonoBehaviour mono)
{
    if (moveRoutine != null)
    {
        mono.StopCoroutine(moveRoutine);
    }
    moveRoutine = _InvokeAnim(timeBeforeStart, MoveFunction, mono);
}
IEnumerator _InvokeAnim(float timeBeforeStart, Action<MonoBehaviour> MoveFunction, MonoBehaviour mono)
{
    yield return new WaitForRealSecondsClass().WaitForRealSeconds(timeBeforeStart, mono);
    MoveFunction(mono);
}

And the Move(MonoBehaviour mono) itself:

public void Move(MonoBehaviour mono)
{
    if (moveRoutine != null)
    {
        mono.StopCoroutine(moveRoutine);
    }
    moveRoutine = _Move(from, to, overTime, mono);
    mono.StartCoroutine(moveRoutine);
}

What I tested and worked is the Move itself, the WaitForRealSeconds I used in another project for UI waiting when the game was stopped, it was fine then. As I said I have many methods to invoke, all of them return void and have a parameter MonoBehaviour. Currently it doesn't do anything and I have no idea why.


Solution

  • Sod it, I was dump enough to forget actually Starting that coroutine.

    In my Invoke:

            public void InvokeAnim(float timeBeforeStart, Action<MonoBehaviour> MoveFunction,
            MonoBehaviour mono)
        {
            if (moveRoutine != null)
            {
                mono.StopCoroutine(moveRoutine);
            }
            moveRoutine = _InvokeAnim(timeBeforeStart, MoveFunction, mono);
            mono.StartCoroutine(moveRoutine); //one line was missing
        }
        IEnumerator _InvokeAnim(float timeBeforeStart, Action<MonoBehaviour> MoveFunction,
            MonoBehaviour mono)
        {
            yield return new WaitForRealSecondsClass().WaitForRealSeconds(timeBeforeStart, mono);
            MoveFunction(mono);
        }