Search Unity

Coroutine not working every time

Discussion in 'Scripting' started by kpetkov, Mar 3, 2018.

  1. kpetkov

    kpetkov

    Joined:
    Mar 3, 2018
    Posts:
    12
    HI, I am using a simple coroutine:
    IEnumerator nextFigureTimer() {
    yield return new WaitForSeconds (5f);
    Debug.Log("Coroutine executed");
    prepareNextFigure = true;
    }

    and somewhere in Update I call it:

    Debug.Log("Before calling coroutine");
    StartCoroutine(nextFigureTimer());

    but it is not executed every time, At some point I can't see the message "Coroutine executed", while I see "Before calling coroutine" every time. And my game is not working properly because prepareNextFigure flag is not updated. Does Someone knows the reason why this is happening? And what the appropriate solution will be ?
    Thanks
     
  2. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,819
    You have to be careful about calling a coroutine in update because it is calling it every frame unless you set boolean flags to stop it. So you are calling it 60 times per second. You'd have to show more code to see what you can do about it.
     
  3. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    I agree completely with @fire7side : Make sure it's not calling it all the time; you can post your code if you're unsure.

    One other thing that people don't always know when they are new, is that if you deactivate the game object, the coroutine will not continue to run.. so make sure you haven't done that.
     
  4. kpetkov

    kpetkov

    Joined:
    Mar 3, 2018
    Posts:
    12
    this is the code. Flags are updated in different places and control the code flow
    Code (CSharp):
    1.  
    2. void Start() {
    3.        // some other code ....
    4.        // ....
    5.        // end other code
    6.        GameUtility.levelStarted = true;
    7.     }
    8.  
    9.     IEnumerator nextFigureTimer() {
    10.         yield return new WaitForSeconds (5f);
    11.  
    12.         GameUtility.prepareNextFigure = true;
    13.     }
    14.  
    15.    void Update () {
    16.         if (GameUtility.levelStarted && !GameUtility.levelEnded)
    17.         {
    18.             // Stop game execution
    19.             if (GameUtility.gameOver)
    20.             {
    21.              
    22.                 GameUtility.gameOver = false;
    23.                 GameUtility.levelEnded = true;
    24.  
    25.                 LevelComplete();
    26.                 return;
    27.             }
    28.  
    29.             if (spawner.totalPlacedFigures == 0 && spawner.totalGeneratedFigures == 0)
    30.             {
    31.                 spawner.CreateNextFigure();
    32.  
    33.                 GameUtility.ActivateNextFigure();
    34.             }
    35.  
    36.             if (GameUtility.figurePlaced)
    37.             {
    38.                 GameUtility.figurePlaced = false;
    39.  
    40.                 iterationCounter++;
    41.  
    42.                 // Start Moving prepared figure
    43.                 GameUtility.playerFigure.GetComponent<FigureColliding>().enabled = true;
    44.                 GameUtility.playerFigure.GetComponent<MoveFigure>().enabled = true;
    45.                 GameUtility.playerFigure.GetComponent<SetSortingLayer>().sortingOrder = GameUtility.currentSortingOrder;
    46.                 GameUtility.currentSortingOrder++;
    47.  
    48.                 StartCoroutine(nextFigureTimer());
    49.             }
    50.  
    51.             if (GameUtility.prepareNextFigure)
    52.             {
    53.                 GameUtility.prepareNextFigure = false;
    54.  
    55.                 if (spawner.CreateNextFigure())
    56.                 {
    57.                     Debug.Log("All figures are used -> finish level");
    58.                     LevelComplete();
    59.                 }
    60.             }
    61.         }
    62.    }
    63.  
     
    Last edited: Mar 4, 2018
  5. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Pleas read this thread for when you post code on the forums: https://forum.unity.com/threads/using-code-tags-properly.143875/

    Nothing there is really telling me why you wouldn't finish a coroutine.. If the game object isn't disabled (or destroyed) while it's running, and it has started, the coroutine should finish, afaik.
     
  6. kpetkov

    kpetkov

    Joined:
    Mar 3, 2018
    Posts:
    12
    Thanks for pointing me to tagging code. AT one of the code parts I disbale a script for moving, script for colliding is active. WIll try to reorganize the code in order to achieve my goal. Thank you
     
  7. methos5k

    methos5k

    Joined:
    Aug 3, 2015
    Posts:
    8,712
    Well, hope you get it sorted. :)
     
  8. fire7side

    fire7side

    Joined:
    Oct 15, 2012
    Posts:
    1,819
    Using a timer isn't ideal for that situation.
    I'm guessing you are waiting for <MoveFigure> to finish. If that is so, then MoveFigure should supply the ending point for the coroutine.

    Something like:
    Code (csharp):
    1.  
    2. IEnumerator nextFigureTimer() {
    3.  
    4. while(figureMoving == true){
    5. yield return new WaitForSeconds (1f);
    6. Debug.Log("waiting for figureMove");
    7. }
    8. Debug.Log("next figure =true");
    9. prepareNextFigure = true;
    10. }
    11.  
    Then you have MoveFigure change the bool when it is finished. There are other ways, but timers don't always work the way you think they should because programs can bog down, etc.

    If it's just one function you can easily wait for that to finish. Just check the section in the manual on coroutines.

    If it was me, I would move the figure using a coroutine and then just change prepareNextFigure to true when the coroutine was finished.
     
    Last edited: Mar 4, 2018
  9. kpetkov

    kpetkov

    Joined:
    Mar 3, 2018
    Posts:
    12
    Hi all, thank you for supporting me. Since the game actions happening asynchronously I decide to make some code refactoring and now I am using events and delagates to drive code functionality. This solve most of my problems related to figure movement. I realize that coroutines can most likely be used in a places when there have to be some time gaps between actions.