Search code examples
c#unity-game-enginecoroutine

When I add a if condition to my coroutine which starts a decrease in value of oxygen, it makes it deplete really fast


I wanted to add a if condition to my coroutine and it broke it

private void OnTriggerEnter(Collider other)
{
    if (other.CompareTag("Water"))
    {
        isSwimming = true;
        rb.useGravity = false;
        rb.velocity = Vector3.zero;
        isUnderwater = true;
        isFallingToSurface = true; // Start falling to the water surface
    }
}
IEnumerator decreaseOxygen()
{
    while(true)
    {
        currentOxygenPercent -= 1; 
        yield return new WaitForSeconds(1);
    }
}

// Update is called once per frame
void Update()
{
    if (pC.isUnderwater == true)
    {
        StartCoroutine(decreaseOxygen());
    }
    else
    {
        StopCoroutine(decreaseOxygen());
    }

the first code is the condition for when isUnderwater is active and the second code is how i tried to implement an if condition to start the coroutine, im fairly new to coding so feedback and criticism is welcome

I tried many ways to the best of my ability to fix the problem but i feel like to coroutine is constantly starting in a nanosecond loop which is the reason why the value of the oxygen is depleting so fast


Solution

  • An alternative solution would be to start the coroutine immediately (in something like Start) and check the isUnderwater variable inside the coroutine instead of every frame in Update (As Jon Skeet suggested):

    public void Start()
    {
        StartCoroutine(decreaseOxygen());
    }
    
    IEnumerator decreaseOxygen()
    {
        WaitForSeconds oneSecond = new(1);
        while(true)
        {
            if (pC.isUnderwater)
            {
                currentOxygenPercent -= 1;
            }
            yield return oneSecond;
        }
    }
    

    This way you wouldn't have to manage stopping/starting the coroutine. This would mean that the oxygen percentage would be tied to a "global" (always running) 1 second timer, rather than the timer starting when you enter the water.