Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Problem with Coroutine

Discussion in 'Scripting' started by ExoAve, Feb 20, 2015.

  1. ExoAve

    ExoAve

    Joined:
    Jan 26, 2015
    Posts:
    11
    Hi guys! (and girls!) :)
    I want to wait in my code at some point, it's a zombie spawner, and i want it to spawn a zombie every 3 second (for example). Here's the code:
    Code (CSharp):
    1. public class SpawnZombie : MonoBehaviour
    2. {
    3.     public Transform player;
    4.     public int NumberOfZombies;
    5.     public GameObject Zombie;
    6.  
    7.     private int range;
    8.     // Use this for initialization
    9.     void Start ()
    10.     {
    11.         range = 50;
    12.     }
    13.    
    14.     // Update is called once per frame
    15.     void Update ()
    16.     {
    17.         while (Vector3.Distance(transform.position, player.position) < range && NumberOfZombies > 0)
    18.         {
    19.             StartCoroutine(SpawnZombies());
    20.         }
    21.     }
    22.  
    23.     IEnumerator SpawnZombies()
    24.     {
    25.         GameObject instanceZombie = Instantiate(Zombie, transform.position, Quaternion.identity) as GameObject;
    26.         instanceZombie.GetComponent<Zombie>().player = player;
    27.         NumberOfZombies -= 1;
    28.         yield return new WaitForSeconds(3.0f);
    29.     }
    30. }
    31.  
    I've read again and again the documentation, but i can't find my mistake, the script keep making all the zombies spawn at the same time.

    Thanks for your help! :)
     
  2. Aidy

    Aidy

    Joined:
    Oct 15, 2014
    Posts:
    19
    Hi there,

    I can't really offer any advice as to why that isn't working, unfortunately, I'm not massively familiar with coroutines (even though I should be by now!). Though there's a good Unity tutorial explaining how to do a spawner via a script that doesn't use a coroutine, but instead just uses InvokeRepeating. It's here, if you're interested. If that's not what you're after, then I hope you find your answer!
     
  3. AlucardJay

    AlucardJay

    Joined:
    May 28, 2012
    Posts:
    328
    You are calling the Coroutine every Update (when condition is met). so basically starting many coroutines. AND you are running a while loop in Update which is really scary.

    You need a boolean to see if the coroutine is not running before calling it again in Update.(and fix the while in Update, as Update already runs once per frame) :

    Code (csharp):
    1.  
    2. private bool isSpawning = false;
    3.  
    4. .... all your other code
    5.  
    6. void Update ()
    7. {
    8.    if ( isSpawning == false ) // check if spawning
    9.    {
    10.      if (Vector3.Distance(transform.position, player.position) < range && NumberOfZombies > 0) // check distance
    11.      {
    12.        StartCoroutine(SpawnZombies());
    13.      }
    14.    }
    15. }
    16.  
    17. IEnumerator SpawnZombies()
    18. {
    19.    isSpawning = true; // NOW SPAWNING
    20.    GameObject instanceZombie = Instantiate(Zombie, transform.position, Quaternion.identity) as GameObject;
    21.    instanceZombie.GetComponent<Zombie>().player = player;
    22.    NumberOfZombies -= 1;
    23.    yield return new WaitForSeconds(3.0f);
    24.    isSpawning = false; // ok, spawning delay has ffinished
    25. }
     
  4. ExoAve

    ExoAve

    Joined:
    Jan 26, 2015
    Posts:
    11
    Ok thank you alucard, indeed it was stupid ^^ i will try when i get home, thanks for the help :)