0
\$\begingroup\$

I have a Coroutine (X) that waits for seconds before it does something. However, during that time there is another Coroutine that may trigger (Y), and during the time it's on X has to pause waiting for seconds, until Y finishes its job. The point is not to waste the wait time of X.

Pausing the game is not possible since everything else has to work during that time.

I tried to add the bool isLightningAbilityRunning that checks if Y is running, but since X is not repeating itself and just waiting, it doesn't get to that point.

The whole X coroutine:

 private IEnumerator TriggerGravityAbility() {
    var gravityDuration = gravityInitialDuration + UpgradeManager.instance.GravityDurationUpgrade();
    AudioManager.instance.PlayGravitySound();
    CubeSpawner.instance.gameObject.SetActive(false); // Stop spawning cubes
    Physics2D.gravity = new Vector2(0f, 1f);
    ParticleModifier.instance.SetGravity(0f);
    CubeBehavior.instance.border.isTrigger = false;
    CubeBehavior.instance.ignoreBorderLightning = true;

    while (isLightningAbilityRunning) {
            yield return null;
    }

    yield return new WaitForSeconds(gravityDuration);

    CubeBehavior.instance.DestroyOutOfCameraCubes();

    CubeSpawner.instance.gameObject.SetActive(true); // Start spawning cubes    
    Physics2D.gravity = new Vector2(0f, -9.81f);
    ParticleModifier.instance.ResetGravity();
    CubeBehavior.instance.border.isTrigger = true;
    CubeBehavior.instance.ignoreBorderLightning = false;
}

How can I make this work?

\$\endgroup\$
1
\$\begingroup\$

Have a boolean flag that indicates if Coroutine Y is running at the instant:

bool isYRunning = false;

IEnumerator Y
{
    isYRunning = true;

    //stuff...

    isYRunning = false;
}

And in X, have something like this:

int waitAmount = 10, waited = 0;

IEnumerator X
{
    //stuff...

    while(waited < waitAmount)
    {
        if(!isYRunning)
        {
            waited += Time.deltaTime;
        }

        yield return null;
    }

    waited = 0;
}

Notice that we only increment the waited time if Y is not running.

\$\endgroup\$
0
\$\begingroup\$

If I understand you, the total wait time should be gravityDuration plus however long Y takes to run. The straightforward way to solve this would be to let TriggerGravityAbility also trigger Y:

private IEnumerator TriggerGravityAbility() {
    float preDuration = gravityDuration * 0.2f;
    float postDuration = gravityDuration * 0.8f;

    yield return new WaitForSeconds(preDuration);
    yield return StartCoroutine(Y());
    yield return new WaitForSeconds(postDuration);
}

If TriggerGravityAbility can't be responsible for running Y, the solution is less clean (countdown timers are usually a bad habit, but this case warrants it):

private IEnumerator TriggerGravityAbility()
{
    float durationCountdown = gravityDuration;
    while (durationCountdown > 0)
    {
        if (!isLightningAbilityRunning)
            durationCountdown -= Time.deltaTime; // the timer is not running during lightning
        yield return null;
    }
}
\$\endgroup\$
  • \$\begingroup\$ I think he wants to make "Y" added to the wait time dynamically (i.e. only if Y is executed). I'm not coding expert, but that doesn't seem possible (at least not that way). \$\endgroup\$ – Nikaas Jul 28 '16 at 3:45
  • \$\begingroup\$ That's what my code does. It pauses the timer of "X" while "Y" is running. \$\endgroup\$ – piojo Jul 29 '16 at 8:32
  • \$\begingroup\$ @piojo Y should not trigger every time X is on, it's its own thing. X just has to wait if Y is doing stuff. \$\endgroup\$ – Milen Aug 1 '16 at 0:40
  • \$\begingroup\$ @Milen That's what the second half of my answer says. \$\endgroup\$ – piojo Aug 3 '16 at 4:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.