Coroutine no execute after WaitForSeconds [SOLVED] Use WaitForSecondsRealtime

I have a problem in a code that I am doing. Basically I want to put a delay on an action.

Then it occurred to me to use a Coroutine. But it is not working, the coroutine is invoked but after the WaitForrSeconds the following code is no longer executed

This is de code

private void OnEnable()
        {
            Debug.Log("OnEnable", gameObject);

            /// other code working

            StartCoroutine(EnableEffect());
        }

        IEnumerator EnableEffect()
        {
            Debug.Log("EnableEffect 1");
            yield return new WaitForSeconds(2f);
            Debug.Log("EnableEffect 2");
           //RealMethod();
        }

It is practically a copy of another coroutine that I had to add another delay that I needed
//This code works perfectly

public void OnDead(GameObject gameObject, int playerIndex)
        {
            list.Remove(gameObject);

            proCamera2D.RemoveCameraTarget(gameObject.transform, 1f);

            DrainEnergy();         

            StartCoroutine(WaitDeploy(5.0f, playerIndex));

        }

        IEnumerator WaitDeploy(float waitTime, int playerIndex)
        {
            yield return new WaitForSeconds(waitTime);
            Debug.Log("WaitDeploy " + Time.time, gameObject);


            ReDeploys[playerIndex].playerAssistant.playerId = playerIndex;
            ReDeploys[playerIndex].gameObject.SetActive(true);
        }

Try putting the time as a parameter in the code that doesn’t work, but maintains the bad behavior. The only thing I see differently is that the coroutine that does not work is in an OnEnable method, does that have something to do with the problem?

[EDIT]

The LOG shows the line EnableEffect 1, but not EnableEffect 2

Coroutines can only run on active gameobjects and enabled MonoBehaviours.Since you do this in a method called “OnDead” I would assume that you probably destroy, disable or deactivate the gameobject / monobehaviour. So any coroutine would be terminated.

You could use a seperate object that is staying alive as the coroutine host. For this any monobehaviour singleton would do. Something like I used in my coroutine helper

Ok, the EnableEffect coroutine is invoked on an object that is present in the scene from the beginning but is inactive.

And the method that does work, which is the second, is in an administrator class, which is always alive, rather the object that dies invokes the OnDead.

From what you mention EnableEffect method does not work because the gameObject is not active?

Ohh, so your first snippet is the one that doesn’t work while the second does work? ^^ I got it the other way round. Anyways the reasons are still the same. If a coroutine stops running at a yield statement, you either stopped the coroutine or the object got disabled / deactivated. Keep in mind that a line like this:

StartCoroutine(EnableEffect());

is actually doing this:

this.StartCoroutine(EnableEffect());

StartCoroutine is a member method of the MonoBehaviour class. The coroutine that is created belongs to the “this class”. So it doesn’t matter where the actual code is located, only on which object you call StartCoroutine.

Starting a coroutine inside the OnEnable callback should usually work just fine. Are you sure that you don’t deactivate the object within the next 2 seconds?

That’s right, the object is still alive

[SOLVE]

The invoker of the object after activating it sets the time Scale to 0 (Time.timeScale = 0;), so WaitForSeconds does not work, it must be used instead WaitForSecondsRealtime

4 Likes

Thanks for the trouble Bunny

Ahh yes :slight_smile: That’s also a possible reason I haven’t thought of at the moment ^^. In the end everything can be explained :slight_smile:

Finally !! I’ve been trying to figure out for a long time now why the particle effects I’ve attached to the projectiles were not Despawning properly by my Pooler. When the projectile hits I’m spawning two effects, then StartCoroutine() to despawn them, then Despawning the projectile right away … so the StartCoroutine() wasn’t actually firing.

So now to figure out to fix it …