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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

StartCoroutine() doesn't works if called in a method other than Start()

Discussion in 'Scripting' started by OldHarryMTX, Apr 4, 2020.

  1. OldHarryMTX

    OldHarryMTX

    Joined:
    Sep 18, 2018
    Posts:
    45
    Hi all
    When i try to call a coroutine from a method other than Start() the StartCoroutine() command doesn't work.

    Code (CSharp):
    1. public class ExempleClass: MonoBehaviour
    2. {
    3.     private void Start()
    4.     {
    5.         //StartCoroutine(ExempleCoroutine());
    6.     }
    7.  
    8.     public void OtherMethod()
    9.     {
    10.         Debug.Log("OtherMethod");
    11.         StartCoroutine(ExempleCoroutine());
    12.     }
    13.  
    14.     IEnumerator ExempleCoroutine()
    15.     {
    16.         while (true)
    17.         {
    18.             yield return new WaitForSeconds(0.1f);
    19.             Debug.Log("ExempleCoroutine");
    20.         }
    21.     }
    22. }
    For exemple, if i try to use the code above, the coroutine works properly if called it from inside the Start(), but is completely ignore if called from OtherMethod(), even if the Debug.Log("OtherMethod") print the message correctly.

    I have tryed to change the StartCoroutine(ExempleCoroutine()) in StartCoroutine("ExempleCoroutine") but nothing. I have also tryed to link VisualStudio to Unity and add some break points, the StartCoroutine(ExempleCoroutine()) command is completely ignored, and the code coninues regularly.

    Do you know why it behave this way? I have found some other topic in UnityAnswer for similar problem, but none with a good solution.
     
  2. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,064
    This should work perfectly fine. However, if you call
    OtherMethod
    on a
    GameObject
    that is not enabled, this will fail. Because
    Coroutines
    require an active
    GameObject
    . Once the
    Coroutine
    runs and the
    GameObject
    is set inactive, it will kill the
    Coroutine
    as well.
     
    Kurt-Dekker likes this.
  3. OldHarryMTX

    OldHarryMTX

    Joined:
    Sep 18, 2018
    Posts:
    45
    HI Masked Mouse. The go is active and never destroyed, and the game does not change scene or anything else that can disable the go.

    I noticed one thing. If I call
    OtherMethod()
    from
    Start()
    it works. Can it depend on the fact that it is normally invoked by an
    Action
    object? It seems incredible to me that the cause is this, since the
    Debug.Log()
    inside it always works and only the
    StartCoroutine()
    is ignored, but I have run out of plausible solutions.
     
  4. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,064
    T̶h̶a̶t̶’̶s̶ ̶b̶e̶c̶a̶u̶s̶e̶ ̶y̶o̶u̶ ̶h̶a̶v̶e̶ ̶t̶o̶ ̶c̶a̶l̶l̶ ̶O̶t̶h̶e̶r̶M̶e̶t̶h̶o̶d̶ ̶f̶r̶o̶m̶ ̶s̶o̶m̶e̶w̶h̶e̶r̶e̶ ̶:̶p̶ ̶A̶w̶a̶k̶e̶,̶ ̶S̶t̶a̶r̶t̶,̶ ̶O̶n̶E̶n̶a̶b̶l̶e̶,̶ ̶O̶n̶D̶i̶s̶a̶b̶l̶e̶,̶ ̶O̶n̶D̶e̶s̶t̶r̶o̶y̶ ̶a̶r̶e̶ ̶m̶e̶t̶h̶o̶d̶s̶ ̶t̶h̶a̶t̶ ̶U̶n̶i̶t̶y̶ ̶i̶n̶v̶o̶k̶e̶s̶.̶

    if you have a UI button and hook up your game object with the script & method in the on click. It should work.
    Your method isn’t going to be magically invoked by itself, it has to be invoked from somewhere
     
    Last edited: Apr 5, 2020
  5. OldHarryMTX

    OldHarryMTX

    Joined:
    Sep 18, 2018
    Posts:
    45
    Lol, MaskedMouse, OtherMethod IS called from somewhere. It is called from a method that is Invoked using a delegate Action, which in turn is invoked in an asynchronous class that exchanges commands via a custom Tcp network, all of which can be traced back to the initial Start() and Update() methods.

    Again, the Debug.Log inside OtherMethod works fine, so the method is called.

    I think the problem, however, is the fact that the action is invoked by an asynchronous method.
     
  6. Yoreki

    Yoreki

    Joined:
    Apr 10, 2019
    Posts:
    2,590
    Please take a moment and actually read OPs post. It was mentioned that the Coroutine does not start, despite the Debug.Log message in OtherMethod getting printed. He did call OtherMethod from somewhere.

    @OldHarryMTX Just to make this absolutely clear: you are not calling OtherMethod from a different thread? Most of Unity only works on the mainthread. I'm actually not sure if this goes for Coroutines, but it should. Either way it should throw an exception i guess. So the next question would be.. are you sure there are no exceptions?
     
  7. MaskedMouse

    MaskedMouse

    Joined:
    Jul 8, 2014
    Posts:
    1,064
    right, I responded just before sleeping and now just when I woke up.
    StartCoroutine cannot be called from a thread, has to be done on the main thread.
     
    Last edited: Apr 5, 2020
  8. OldHarryMTX

    OldHarryMTX

    Joined:
    Sep 18, 2018
    Posts:
    45
    At this point i'm not sure of that... OtherMethod is assigned to an Action Object located in a non Mono class (lets call it TcpClientClass), and this Action is invoked when TcpClientClass receive a message from the network, in an Async Method, recognized as a command.

    I think this is the problem.

    I solved this calling the coroutine in the Start() and changing it in something like this:

    Code (CSharp):
    1. IEnumerator ExempleCoroutine()
    2.     {
    3.         while (true)
    4.         {
    5.             yield return new WaitForSeconds(0.1f);
    6.  
    7.             if (startCoroutine)
    8.             {
    9.                     //Do something//
    10.                     startCoroutine= false;
    11.                     yield break;
    12.             }
    13.         }
    14.     }
    using the Action to invoke a Method that only set the bool startCoroutine as true.

    In that way it works.