Problem with Coroutine

Hi guys! (and girls!) :slight_smile:
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:

public class SpawnZombie : MonoBehaviour
{
    public Transform player;
    public int NumberOfZombies;
    public GameObject Zombie;

    private int range;
    // Use this for initialization
    void Start ()
    {
        range = 50;
    }
   
    // Update is called once per frame
    void Update ()
    {
        while (Vector3.Distance(transform.position, player.position) < range && NumberOfZombies > 0)
        {
            StartCoroutine(SpawnZombies());
        }
    }

    IEnumerator SpawnZombies()
    {
        GameObject instanceZombie = Instantiate(Zombie, transform.position, Quaternion.identity) as GameObject;
        instanceZombie.GetComponent<Zombie>().player = player;
        NumberOfZombies -= 1;
        yield return new WaitForSeconds(3.0f);
    }
}

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! :slight_smile:

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!

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) :

private bool isSpawning = false;

.... all your other code

void Update ()
{
   if ( isSpawning == false ) // check if spawning
   {
     if (Vector3.Distance(transform.position, player.position) < range && NumberOfZombies > 0) // check distance
     {
       StartCoroutine(SpawnZombies());
     }
   }
}

IEnumerator SpawnZombies()
{
   isSpawning = true; // NOW SPAWNING
   GameObject instanceZombie = Instantiate(Zombie, transform.position, Quaternion.identity) as GameObject;
   instanceZombie.GetComponent<Zombie>().player = player;
   NumberOfZombies -= 1;
   yield return new WaitForSeconds(3.0f);
   isSpawning = false; // ok, spawning delay has ffinished
}

Ok thank you alucard, indeed it was stupid ^^ i will try when i get home, thanks for the help :slight_smile: