Search Unity

Coroutine doesn't invoke my function after reload level

Discussion in 'Scripting' started by mk22, May 8, 2015.

  1. mk22

    mk22

    Joined:
    Feb 1, 2015
    Posts:
    51
    Hey,

    I have a problem with Coroutine. I have two scenes: Menu and Game.
    In the Game scene I have a button "return to menu" and in the Menu I have button play ( what brings me back to the Game scene).

    I use two different scripts in those scenes.
    In the Game I have:
    Code (CSharp):
    1. private IEnumerator myCoroutine;
    2.  
    3. public void myFunction() { ...... }
    4.  
    5. void Start ()
    6. {
    7.     myCoroutine = WaitAndDo( 0.4f, myFunction);
    8.     StartCoroutine(  myCoroutine );
    9. }
    10.  
    11. IEnumerator WaitAndDo(float time, DelayedMethod method)
    12.     {
    13.         while (true)
    14.         {
    15.             yield return new WaitForSeconds (time);
    16.  
    17.             method ();
    18.  
    19.         }
    20.     }
    It works fine when: PlayButton (Menu) -> load level Game
    But when I try to reload Game:
    PlayButton ( in Menu) -> load level Game -> Back To Menu Button -> PlayButton ( in Menu) -> load level Game

    Code (CSharp):
    1.     method ();
    doesn't invoke.
    I debugged it in MonoDevelop and it stops in
    Code (CSharp):
    1. yield return new WaitForSeconds (time);

    Do you know why?
    Thanks
     
  2. StarManta

    StarManta

    Joined:
    Oct 23, 2006
    Posts:
    8,775
    When you run a coroutine, it's being run on the object. If that object is destroyed (and, I think, also when it is deactivated), then it stops running. I see 2 simple options:

    1) You can set a static "flag" variable that your component checks at Start():
    Code (csharp):
    1.  
    2. private static bool doThatThingOnStart = false;
    3. void Start() {
    4. if (doThatThingOnStart) {
    5. DoThatThing();
    6. doThatThingOnStart = false;
    7. }
    8. }
    9.  
    And make sure that doThatThingOnStart is set to true if your script is waiting to DoThatThing(). static variables are per class (not per object), and persist when all your objects have been destroyed (though not across player sessions).

    2) You can use DontDestroyOnLoad to make your object persist across scenes, and the coroutine will continue. Be aware that when you re-load your scene you will likely now have two of these things in the scene, so you may have to code around that.
     
  3. mk22

    mk22

    Joined:
    Feb 1, 2015
    Posts:
    51
    @StarMania thanks for help.

    I've just found the answer. I stoped time when I clicked Pause Button
    Code (CSharp):
    1. Time.timeScale = 0;
    When I reload Game timeScale is still 0.

    I put
    Code (CSharp):
    1. Time.timeScale = 1;
    in my Start() function for restart it. Now it works ok.
     
  4. moh05

    moh05

    Joined:
    Nov 26, 2015
    Posts:
    65
    Hello,

    I have the same problem, but my timeScale is still 1.

    Any other solution?
     
  5. AibNihan

    AibNihan

    Joined:
    Jan 17, 2017
    Posts:
    5
    Are You Find Any Solution ?
     
  6. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    If you have an issue that you believe was not solved in this thread, create your own and post your code and whatever's happening and/or wrong. :)
    The last message here was over a year ago and that person was bumping an older message, etc.. you get the idea :)
     
    AibNihan likes this.
  7. AibNihan

    AibNihan

    Joined:
    Jan 17, 2017
    Posts:
    5
    Thank you so much for your reply. Actually, I find My Solution :) Thank you again :)