Search Unity

StartCoroutine and Yield not working.

Discussion in 'Scripting' started by Vildez, Oct 8, 2014.

  1. Vildez

    Vildez

    Joined:
    Oct 8, 2014
    Posts:
    20
    Hey guys I am very new to unity and have a fairly good understanding of C# as that is what I am choosing to use for my scripting language. Currently I'm working on my first little test project that is a carnival type game where rubber ducks scroll across the screen and you click them to knock them down. However I have noticed that I am getting some lag issues doing it the way I have it setup up now and want to have the ducks respawn at certain intervals. Here is the code I am using so far.
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Linq.Expressions;
    5.  
    6. public class scriptDuckControler : MonoBehaviour {
    7.  
    8.     private Vector3 _duckLeftPOS = new Vector3(3.4f, 0.88f, 0f);
    9.     private Vector3 _duckRightPOS = new Vector3(-3.2f, -0.7f, 0f);
    10.     public GameObject _duckLeft;
    11.     public GameObject _duckRight;
    12.    
    13.     // Update is called once per frame
    14.     void Update ()
    15.     {
    16.         if (transform.tag == "duck_left")
    17.         {
    18.             if (this.transform.position.x <= -4.2)
    19.             {
    20.                 StartCoroutine(SpawnDuck(true));              
    21.                 GameObject.Destroy(this.gameObject);
    22.             }
    23.             else
    24.             {
    25.                 this.transform.Translate(-.045f, 0, 0);
    26.             }
    27.         }
    28.         else if (transform.tag == "duck_right")
    29.         {
    30.             if (this.transform.position.x >= 4.0f)
    31.             {
    32.                 StartCoroutine(SpawnDuck(false));              
    33.                 GameObject.Destroy(this.gameObject);
    34.             }
    35.             else
    36.             {
    37.                 this.transform.Translate(.045f, 0, 0);
    38.             }
    39.         }
    40.     }
    41.  
    42.     IEnumerator SpawnDuck(bool _duck)
    43.     {      
    44.         yield return new WaitForSeconds(3);
    45.  
    46.         if (_duck)
    47.         {
    48.             Instantiate(_duckLeft, _duckLeftPOS, this.transform.rotation);
    49.         }
    50.         else
    51.         {
    52.             Instantiate(_duckRight, _duckRightPOS, this.transform.rotation);
    53.         }
    54.     }
    55. }


    The problem that I am having is that I want to spawn or (Instantiate) the objects in this Test() function. However it doesn't seem to be being called no matter what I do. Is there something that I am missing that is causing this to not call. I understand that the call isn't in the code right now but I have tried putting it everywhere in this function and it still doesn't get executed. I have also tried putting it into the Start() function as well and still no dice. Any help would be greatly appreciated. Thanks!
     
    Last edited: Oct 8, 2014
  2. Pirs01

    Pirs01

    Joined:
    Sep 30, 2012
    Posts:
    389
  3. Vildez

    Vildez

    Joined:
    Oct 8, 2014
    Posts:
    20
    As I stated I understand that I am not calling it in the code as I posted it. However, I have tried putting the StartCoroutine(test()); in several places of the code and still it is not called or executed. Is there something else that I could be missing that would not be letting this execute?
     
  4. Pirs01

    Pirs01

    Joined:
    Sep 30, 2012
    Posts:
    389
    I understand you said you don't have the call in posted code and that's good because as I said it's incorrect to call a coroutine. As you later suggested yourself it should be passed as argument to StartCoroutine function and that should work.

    If you post the actuall code that doesn't work as expected then I can comment on that but otherwise I cannot comment on why your hypothetical code doesn't work. Also please read and apply the first link provided if you expect anyone to read the code you post.
     
  5. Cpt Chuckles

    Cpt Chuckles

    Joined:
    Dec 31, 2012
    Posts:
    86
    i'm trying to show how to use code tags but it's not working out real well. gimme a minute

    [ code ] code tags [ /code ]

    there, just take out the spaces and put your code in it so all the code formatting looks nice and orderly instead of pasted all up in the post like regular text

    edit: see now isn't that better :>

    also, you gotta indent that code bruh. is it indented in the original script? if so, re-paste it into the code tags so we get the indented version, it's hard to read without indenting.
     
  6. Vildez

    Vildez

    Joined:
    Oct 8, 2014
    Posts:
    20
    Okay there is the full code of what I am trying to use and the SpawnDuck(bool _duck) is not being executed. Sorry for the poorly pasted code should all be fixed now.
     
  7. Pirs01

    Pirs01

    Joined:
    Sep 30, 2012
    Posts:
    389
    Looks good to me. Try putting Debug.Log-s before every StartCoroutine call and inside your coroutine to see what get's called and what doesn't. Put one in first line of Update also to make sure your component is working at all.
     
  8. Vildez

    Vildez

    Joined:
    Oct 8, 2014
    Posts:
    20
    trying to put in my code Debug.Log-s; and it doesn't accept it.
     
  9. Pirs01

    Pirs01

    Joined:
    Sep 30, 2012
    Posts:
    389
  10. Vildez

    Vildez

    Joined:
    Oct 8, 2014
    Posts:
    20
    Okay so I know that the main script is working as my ducks are moving across the screen and when hitting the x value I have set are getting destroyed. However, they are still not calling the CoRoutine and spawning the new ducks.
     
  11. Pirs01

    Pirs01

    Joined:
    Sep 30, 2012
    Posts:
    389
    By main script I assume you mean some script other then this one because this one has no code for input handling or moving ducks. so it's not really relevant. Put the Log-s as I requested and report on what gets called and what doesn't. Also please post the code after putting the Log-s in jus to make sure we're on the same page.
     
  12. Vildez

    Vildez

    Joined:
    Oct 8, 2014
    Posts:
    20
    Okay by main script I mean that I have two ducks in my scene and they move automatically across the screen with this script as you see below:
    Code (CSharp):
    1. if (transform.tag == "duck_left")
    2.         {
    3.             if (this.transform.position.x <= -4.2)
    4.             {
    5.                 StartCoroutine(SpawnDuck(true));            
    6.                 GameObject.Destroy(this.gameObject);
    7.             }
    8.             else
    9.             {
    10.                 this.transform.Translate(-.045f, 0, 0);
    11.             }
    12.         }
    13.         else if (transform.tag == "duck_right")
    14.         {
    15.             if (this.transform.position.x >= 4.0f)
    16.             {
    17.                 StartCoroutine(SpawnDuck(false));            
    18.                 GameObject.Destroy(this.gameObject);
    19.             }
    20.             else
    21.             {
    22.                 this.transform.Translate(.045f, 0, 0);
    23.             }
    I am trying to figure out what you meant by the Debug.Log -s and I have read the documentation but I can't seem to figure out how to get that to work.
     
  13. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    You're starting a coroutine and then destroying the object that's supposed to run that coroutine.
     
  14. Pirs01

    Pirs01

    Joined:
    Sep 30, 2012
    Posts:
    389
    Code (CSharp):
    1. using UnityEngine;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using System.Linq.Expressions;
    5.  
    6. public class scriptDuckControler : MonoBehaviour {
    7.  
    8.     private Vector3 _duckLeftPOS = new Vector3(3.4f, 0.88f, 0f);
    9.     private Vector3 _duckRightPOS = new Vector3(-3.2f, -0.7f, 0f);
    10.     public GameObject _duckLeft;
    11.     public GameObject _duckRight;
    12.  
    13.     // Update is called once per frame
    14.     void Update ()
    15.     {
    16.         Debug.Log("Update method called!");
    17.         if (transform.tag == "duck_left")
    18.         {
    19.             if (this.transform.position.x <= -4.2)
    20.             {
    21.                 Debug.Log("Starting coroutine: SpawnDuck(true)!");
    22.                 StartCoroutine(SpawnDuck(true));              
    23.                 GameObject.Destroy(this.gameObject);
    24.             }
    25.             else
    26.             {
    27.                 this.transform.Translate(-.045f, 0, 0);
    28.             }
    29.         }
    30.         else if (transform.tag == "duck_right")
    31.         {
    32.             if (this.transform.position.x >= 4.0f)
    33.             {
    34.                 Debug.Log("Starting coroutine: SpawnDuck(false)!");
    35.                 StartCoroutine(SpawnDuck(false));              
    36.                 GameObject.Destroy(this.gameObject);
    37.             }
    38.             else
    39.             {
    40.                 this.transform.Translate(.045f, 0, 0);
    41.             }
    42.         }
    43.     }
    44.  
    45.     IEnumerator SpawnDuck(bool _duck)
    46.     {
    47.         Debug.Log("Coroutine called! Will wait 3 sec now...");
    48.         yield return new WaitForSeconds(3);
    49.         Debug.Log("Coroutine called again after waiting 3 sec!");
    50.  
    51.         if (_duck)
    52.         {
    53.             Instantiate(_duckLeft, _duckLeftPOS, this.transform.rotation);
    54.         }
    55.         else
    56.         {
    57.             Instantiate(_duckRight, _duckRightPOS, this.transform.rotation);
    58.         }
    59.     }
    60. }
    Run and check output to see what gets called and waht doesn't.
     
  15. Pirs01

    Pirs01

    Joined:
    Sep 30, 2012
    Posts:
    389
    Is that how that works? I imagined coroutines are handled somewhere else, far away.

    Is there any resource that discusses how coroutines are handled in detail?
     
  16. Vildez

    Vildez

    Joined:
    Oct 8, 2014
    Posts:
    20
    so should I make a totally different script that handles the spawning of the object. If I'm understanding correctly what your saying is that the co-routine isn't being executed because the object is being destroyed and therefor stopping the script in it's entirety?
     
  17. Pirs01

    Pirs01

    Joined:
    Sep 30, 2012
    Posts:
    389
    Well yes destroing GameObject also destroyes all it's components includint this script.

    However the Destroy takes effect after the current Update loop so the coroutines should be called once before it happens unless the coroutines don't get started right away either. You claimed they don't get called at all.

    From design point of view doesn't make much sens that one duck controller is responsible for creating other ducks. Should be something else handling the duck creation.
     
  18. KelsoMRK

    KelsoMRK

    Joined:
    Jul 18, 2010
    Posts:
    5,539
    Coroutines will execute to the point of encountering a yield statement as soon as they are called. While I believe there is a single registration/management point for all active coroutines, I would be surprised if destroying a GameObject wouldn't unregister associated coroutines simply because there is nothing in the documentation instructing you to call StopAllCoroutines() before calling Destroy().
     
  19. Vildez

    Vildez

    Joined:
    Oct 8, 2014
    Posts:
    20
    Okay I will try and create another script that handles spawning the GameObjects (duck) instead of running it in one script.