6

Okay so I have a pretty good idea of how to use co-routines in Unity3d but I want to make a reusable component for deferred execution that allows me to take code like this

StartCoroutine(WaitForDamageCooldown(DamageCooldown));

IEnumerator WaitForDamageCooldown(float duration)
{
    yield return new WaitForSeconds(duration);
    HasTempInvincibility = false;
}

Taking that and convert it to something like this

CoroutineUtil.DeferredExecutor(float waitTime,Action onComplete);

To be used like this

StartCoroutine(CoroutineUtil.DeferredExecutor(WaitTime, () =>
{
    Debug.Log("DeferredExecutor wait complete");
    HasTempInvincibility = false;
}));

I've tried implementing that in the following

using System;
using System.Collections;
using UnityEngine;

public static class CoroutineUtil
{
    public static IEnumerator DeferredExecutor(float waitDuration, Action onComplete)
    {
        yield return new WaitForSeconds(waitDuration);
        onComplete.Invoke();
    }

    public static IEnumerator DeferredExecutor<T>(float waitDuration, T obj, Action<T> onComplete)
    {
        yield return new WaitForSeconds(waitDuration);
        onComplete.Invoke(obj);
    }
}

thinking that that might not work as a static I've also attempted to add it to the object's class like this

public class Player: MonoBehaviour
{
///....etc
    IEnumerator DeferredExecutor(float waitDuration, Action onComplete)
    {
        yield return new WaitForSeconds(waitDuration);
        onComplete.Invoke();
    }

///....etc
}

The results have been sporadic. I can't figure a rhyme or reason to when the co-routine completes but it does so well after the expected time.

Is there something wrong with my approach

Konamiman
  • 49,681
  • 17
  • 108
  • 138
Terrance
  • 11,764
  • 4
  • 54
  • 80

1 Answers1

0

This does work but, like other coroutines in Unity3d it reflects time from the Time.TimeScale. So because of that 2 seconds isn't necessarily 2 seconds.(Which was my issue)

Time.TimesScale = 1.0f;

That being said the following is how I've been implementing it.

public static IEnumerator DeferredExecutor(float waitDuration, Action onComplete)
{
  yield return new WaitForSeconds(waitDuration);
  onComplete();
}

And this is how I've been using it.

StartCoroutine(CoroutineUtil.DeferredExecutor(2f, () =>
{
  _TimePause.OnPause();
  GameOverCanvas.enabled = true;
}));

This does work but make sure you remember the correct calling conventions. Specifically the StartRoutine

Terrance
  • 11,764
  • 4
  • 54
  • 80