Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question Can't stop coroutine from causing error

Discussion in 'Scripting' started by lordumbilical, Jun 15, 2023.

  1. lordumbilical

    lordumbilical

    Joined:
    May 24, 2020
    Posts:
    38
    "Coroutine couldn't be started because the the game object 'myname' is active!"

    (Also, please note the typographical error in this warning-- "the" is repeated in the editor.)

    I start a simple coroutine that waits 5 seconds and then does something...it's very simple. But if I trigger the coroutine and then end the game before 5 seconds is up, this error occurs. I assume it's because the coroutine is still active. The problem is, I can't find a way to stop the coroutine. I use StopAllCoroutines() on OnDisable(), but that doesn't help (I checked and OnDisable is running correctly). I've tried stopping the coroutine by name and reference. I tried using a boolean to know when the coroutine is already running, and stop it if I try anything like running it again before it has stopped.

    I've read various threads, and I think coroutines should be getting stopped anyway when the game ends, but not sure. And I really have no idea why I can't forcefully stop the coroutine to prevent the error...or how I can prevent this error in general. Im only assuming it is the timer issue causing the error. I use other coroutines similarly and havent had this problem before.

    Anyway pointers appreciated. Thanks.
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,719
    You're probably trying to start the coroutine on your prefab instance, not the instance you made in the scene.

    Pay attention to how Instantiate<T>() works: it returns the new instance. It does NOT magically change what you passed in from a prefab into an instance.
     
  3. lordumbilical

    lordumbilical

    Joined:
    May 24, 2020
    Posts:
    38
    Thanks.
    I'm running the timer coroutine on numerous instantiated clones in the scene. I THINK, but am not sure, the objects having "clone" in their name means they are instances, not linked to the prefab?.

    This is how I do it:

    GameObject module=Instantiate(Resources.Load("Module"), parent) as GameObject;

    And then the module code is calling the coroutine on itself, in its attached script.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,719
    Go look again. GameObjects do not run coroutines. :)

    MonoBehaviours correctly attached to Instantiated GameObjects may run coroutines.

    Here's some more basic terminology reading:

    Unity's component architecture

    https://forum.unity.com/threads/custom-gameobject.967582/#post-6299125

    Terminology primer for assets:

    https://forum.unity.com/threads/con...nto-materials-for-quads.1369056/#post-8632563
     
  5. lordumbilical

    lordumbilical

    Joined:
    May 24, 2020
    Posts:
    38
    I see what you mean. Yes, the asset I am referring to is its own type. The next line of code after instantiating is usually getting the specific asset link, such as MyAsset myAsset = InstantiatedGameObject.GetComponent<MyAsset>();
    ... and that's were the coroutine code runs.
     
  6. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    This is still vague. You really need to look at exactly how and where the
    StartCoroutine
    method is invoked. If you are doing
    someComponent.StartCoroutine(...)
    then the coroutine is running on
    someComponent
    .

    If you are simply writing
    StartCoroutine(..)
    in one of your scripts then the script in which you wrote StartCoroutine is the one the coroutine is running on. You have to be very deliberate and explicit about this.
     
  7. lordumbilical

    lordumbilical

    Joined:
    May 24, 2020
    Posts:
    38
    Yes, the component is running the coroutine on itself. So I have code that states: StartCoroutine(..).
     
  8. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,722
    Which component? Very vague. Without code and an idea of the hierarchy and references involved, we're just guessing.
     
  9. SisusCo

    SisusCo

    Joined:
    Jan 29, 2019
    Posts:
    1,114
    You can use logging to make sure you are looking at the right game object, and to determine what is setting the game object inactive.

    Code (CSharp):
    1. private void MyMethod()
    2. {
    3.     if(gameObject.activeInHierarchy)
    4.     {
    5.         Debug.Log($"{name} in {AssetDatabase.GetAssetOrScenePath(gameObject)} is active.", this);
    6.         StartCoroutine(MyCoroutine());
    7.     }
    8.     else
    9.     {
    10.         Debug.Log($"{name} in {AssetDatabase.GetAssetOrScenePath(gameObject)} is inactive.", this);
    11.     }
    12. }
    13.  
    14. private void OnDisable()
    15. {
    16.     Debug.Log($"{name} in {AssetDatabase.GetAssetOrScenePath(gameObject)} was disabled.", this);
    17. }
    You can click on the messages in your Console to highlight the game object from which they are coming.
     
    Kurt-Dekker likes this.
  10. lordumbilical

    lordumbilical

    Joined:
    May 24, 2020
    Posts:
    38
    Solution:
    if (this.gameObject.activeInHierarchy==false) {
    return;
    }

    I put this immediately before calling the coroutine.
    As part of exiting the game, a trigger activates (because the player component is deactivated and now leaves the trigger area?) and for some reason that trigger code continues to run, calling the coroutine as it normally would, but the parent object is already inactive, but this script is not. Seems to be something about the order that all the scripts and components are turn off when the game exits? I dont disable anything at all, so it's no my doing. Who knows. Im just glad to have hit it on the head.

    Thanks, all.
     
    Last edited: Jun 16, 2023
    SisusCo likes this.