Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice
  2. Ever participated in one our Game Jams? Want pointers on your project? Our Evangelists will be available on Friday to give feedback. Come share your games with us!
    Dismiss Notice

Coroutine stops working after yield return

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

  1. denissuu

    denissuu

    Joined:
    Nov 6, 2019
    Posts:
    112
    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,337
    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:
    364
    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.
     
    denissuu likes this.
  4. denissuu

    denissuu

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