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\$

2 Answers 2

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
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\$
4
  • \$\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
    Commented Jul 28, 2016 at 3:45
  • \$\begingroup\$ That's what my code does. It pauses the timer of "X" while "Y" is running. \$\endgroup\$
    – piojo
    Commented Jul 29, 2016 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\$ Commented Aug 1, 2016 at 0:40
  • \$\begingroup\$ @Milen That's what the second half of my answer says. \$\endgroup\$
    – piojo
    Commented Aug 3, 2016 at 4:02

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .