I have a coroutine that doesn't seem to Stop even after calling StopCoroutine.

I’m trying to make some random flickering in my lights, but give myself the ability to perhaps control when and how long it will flicker for. As such I have created a coroutine to make the light flicker, then a second coroutine that will fire that one but stop it after a given duration, which I am then testing by firing in Start. Using debugging is showing me the StopCoroutine is being called, yet the light still continues to flicker even after. Does anyone have any input on what I may have done wrong?

This is my code, currently:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class LightFlicker : MonoBehaviour
{
    private Light myLight;
    [SerializeField]
    public float minDur = .5f;
    [SerializeField]
    public float maxDur = 3.0f;
    void Start()
    {
        myLight = this.gameObject.GetComponent<Light>();
        StartCoroutine(FlickerLightForDuration(4.0f));
    }

    public IEnumerator FlickeringLight()
    {
            float elapsedTime = 0f;
            float randomDur = Random.Range(minDur, maxDur);
            while (elapsedTime < randomDur)
            {
                myLight.enabled = false;
                yield return new WaitForSeconds(.05f);
                myLight.enabled = true;
                elapsedTime += Time.deltaTime;
                yield return null;
            }//end while time<duration
    }//end FlickeringLight

    public IEnumerator FlickerLightForDuration(float duration)
    {
        StartCoroutine(FlickeringLight());
        yield return new WaitForSeconds(duration);
        StopCoroutine(FlickeringLight());
    }//end FlickerLightForDuration

}//end LightFlicker.cs

Line 36 creates and then stops a fresh coro instance that isn’t even running.

Instead, store the result of the StartCoroutine() call in a Coroutine variable, then hand that variable to StopCoroutine();

1 Like

I’m still fairly new to coroutines. Will you explain how to store the result of the coroutine as a variable? Am I just storing the name as a string?

Your flicker coro would look like this:

public IEnumerator FlickerLightForDuration(float duration)
    {
        // store the running item
        Coroutine flicker = StartCoroutine(FlickeringLight());

        yield return new WaitForSeconds(duration);

        // pass the running item in to be stopped
        StopCoroutine(flicker);
    }//end FlickerLightForDuration

Okay, cool, thanks. Kinda what I was imagining it might be, just was very unsure of the syntax. I’m still trying to build up my coding skills and my confidence in it, so thank you for helping!

1 Like

You’re welcome of course!

Jump in with both feet … doing lots of fun little automated things like flickering lights is a great way to build up confidence and skills. Try lots of different stuff, have a ball… that’s what gamedev is all about!!

Here’s a great inspirational video to push you along the way:

Imphenzia: How Did I Learn To Make Games:

https://www.youtube.com/watch?v=b3DOnigmLBY