Search Unity

Coroutine stops working after yield return

Discussion in 'Scripting' started by denissuu, Mar 12, 2020.

  1. denissuu

    denissuu

    Joined:
    Nov 6, 2019
    Posts:
    162
    Hi there everyone!So, let me tell you about what I'm trying to achieve.Basically, I have a raycast-based interact script that recognizes objects that it hits based on their tags.

    Currently I'm trying to implement a bell that gets ringed on interaction and then after a certain time it's collider becomes enabled again so it can be used once again.The thing is that, I tried using hit.transform.GetComponent<> to try and pull this from another script that was placed on it, but it seems that the coroutine that gets called from the interactscript goes until the first yield return, so it just disables the object and then never gets enabled again.Currently my last try was placing the script on a separate gameobject and calling the gameobject in the interactscript to start the coroutine from that gameobject.

    Here is the current code :

    Code (CSharp):
    1. //This is the interact script part, the other ones work well so this script isn't the issue for sure
    2.  
    3.             if (hit.collider.CompareTag("SchoolBell"))
    4.             {
    5.                 Bell bell = bellScriptObject.GetComponent<Bell>();
    6.                 StartCoroutine(bell.BellChange());
    7.             }
    8.  
    9.  
    10. /* This is the Bell script attached to another gameobject
    11.  that calls on the collider from the proper gameobject
    12. to be disabled and then re-enabled */
    13.  
    14.  
    15. using System.Collections;
    16. using System.Collections.Generic;
    17. using UnityEngine;
    18.  
    19. public class Bell : MonoBehaviour
    20. {
    21.     public BoxCollider boxcoll;
    22.  
    23.     public void Start()
    24.     {
    25.         boxcoll = GetComponent<BoxCollider>();
    26.     }
    27.     public void BellColliderChange()
    28.     {
    29.         StartCoroutine(BellChange());
    30.     }
    31.  
    32.     public IEnumerator BellChange()
    33.     {
    34.         boxcoll.enabled = false;
    35.         Debug.Log("Stonks");
    36.         yield return new WaitForSeconds(3);
    37.         boxcoll.enabled = true;
    38.         Debug.Log("stonks");
    39.     }
    40. }
    41.  
    If anyone has any sort of idea why this isn't working or any suggestions, please let me know!


    Thanks for the help! :)
     
  2. csofranz

    csofranz

    Joined:
    Apr 29, 2017
    Posts:
    1,556
    The coroutine ends because it simply runs to its end. You need a loop after the yield.In the following example, the global 'bellComplete' controls if the bell should stop. When it's true, there is no longer a loop

    Code (CSharp):
    1.   public bool bellComplete = false;
    2.  
    3.  
    4.   public IEnumerator BellChange()
    5.     {
    6.         boxcoll.enabled = false;
    7.         while (!bellComplete){
    8.                 Debug.Log("Stonks");
    9.                 yield return new WaitForSeconds(3);
    10.         }
    11.         boxcoll.enabled = true;
    12.         Debug.Log("stonks");
    13.     }
     
  3. WallaceT_MFM

    WallaceT_MFM

    Joined:
    Sep 25, 2017
    Posts:
    394
    If the coroutine never prints "stonks", then it could be a time scale problem. WaitForSeconds uses scaled time, so if your Time.timeScale is 0, it will never return.
     
    shoopi, glolutphoenix, Atto2O and 3 others like this.
  4. denissuu

    denissuu

    Joined:
    Nov 6, 2019
    Posts:
    162
    My time.timescale never gets modified in any of the scripts, so I don't know if that's really the issue.
     
  5. Rodolfo-Rubens

    Rodolfo-Rubens

    Joined:
    Nov 17, 2012
    Posts:
    1,197
    Hi, sorry to bump this thread. I'm having this same issue, my coroutines won't continue executing after a "yield return Coroutine"...

    Is anyone else having this problem?

    Edit: nevermind, I think is just that recursive coroutine functions just doesn't work I guess.
     
    Last edited: Sep 9, 2020
  6. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    Check for any of the following regarding either coroutine:
    • The MonoBehaviour that started the coroutine was disabled
    • The GameObject that the MonoBehaviour is attached to was deactivated
    • Either of the above was destroyed
    • Timescale was modified (if using a WaitForSeconds or similar)
    • A WaitUntil condition was not met
     
    zanemodell, TrimaXstudio and Rioneer like this.
  7. Rodolfo-Rubens

    Rodolfo-Rubens

    Joined:
    Nov 17, 2012
    Posts:
    1,197
    None of this actually, I edited my post.
     
  8. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    They should, as long as you start them with
    yield return StartCoroutine(MyCoroutine())


    That being said you could probably just solve your use case with a while loop. That might be more readable too.
     
  9. Rodolfo-Rubens

    Rodolfo-Rubens

    Joined:
    Nov 17, 2012
    Posts:
    1,197
    I'm iterating in a tree which makes things confusing for me... but it might work...

    But I think I got it, I was sharing the same reference for all the coroutine executions, when I should use an exclusive reference for the execution start.
     
  10. PraetorBlue

    PraetorBlue

    Joined:
    Dec 13, 2012
    Posts:
    7,909
    Anything you can do with recursion can be done with a Stack data structure. Recursion is essentially just an exploitation of the inherit Stack-like nature of function calls to emulate a Stack.

    Here's an explanation: https://www.tutorialspoint.com/data_structures_algorithms/depth_first_traversal.htm
    Here's a similar algorithm that uses a Queue instead of a stack (and has a different traversal order): https://www.tutorialspoint.com/data_structures_algorithms/breadth_first_traversal.htm

    Those are explanations on a Graph, but a tree is a special case of graph so the same algorithm can be used.
     
  11. Rodolfo-Rubens

    Rodolfo-Rubens

    Joined:
    Nov 17, 2012
    Posts:
    1,197
    Nice, thanks for the links, I will surely give a read!
     
  12. Fumzy567

    Fumzy567

    Joined:
    Feb 18, 2018
    Posts:
    1
    Thank you for this. I had a similar problem. I realized that my while loop kept going and never stopped so it could not go beyond the yield. Thanks