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?
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
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.