Reputation: 130
I wrote a script to spawn game object in my unity game. It uses coroutine. Why my spawnWaves() is called just once? Here is my script:
using UnityEngine;
using System.Collections;
public class GameController : MonoBehaviour {
public GameObject[] hazards;
public Vector3 spawnValues;
public float spawnInterval;
// Use this for initialization
void Start ()
{
StartCoroutine(SpawnWaves(spawnInterval));
}
IEnumerator SpawnWaves(float interval)
{
Vector3 spawnPosition = new Vector3(Random.Range(-spawnValues.x, spawnValues.x), spawnValues.y, spawnValues.z);
Quaternion spawnRotation = new Quaternion(Random.Range(-Mathf.PI, Mathf.PI), Random.Range(-Mathf.PI, Mathf.PI), Random.Range(-Mathf.PI, Mathf.PI), Random.Range(-1f, +1f));
Instantiate(hazards[Random.Range(0, 3)], spawnPosition, spawnRotation);
yield return new WaitForSeconds(interval);
}
}
All public values inside of Unity Editor is set correctly.
What's wrong? Thanks!
Upvotes: 2
Views: 423
Reputation: 29213
The problem is that your method has only one occurrence of yield return
and it's not in a loop. This means that it always returns an IEnumerable
object that contains (yields) a single item from start to end.
The question you have to be able to answer is: how many items do you expect the coroutine to yield?
If you expect it to yield only one item, then it's fine as it is.
If you expect it to yield (for example) 3 items, it would look something like this:
yield return new WaitForSeconds(interval);
yield return new WaitForSeconds(interval);
yield return new WaitForSeconds(interval);
If you expect it to yield n
items, it would look something like:
for(var i = 0; i < n; i++)
{
yield return new WaitForSeconds(interval);
}
If you expect it to yield until a condition is met, then you probably want something like this:
while(!conditionIsMet)
{
yield return new WaitForSeconds(interval);
}
And if you expect it to yield a potentially infinite amount of items:
while(true)
{
yield return new WaitForSeconds(interval);
}
Upvotes: 1
Reputation: 6281
A couroutine is nothing else than a normal yield
-method.
For having a loop use while
.
while (...)
{
// Do work here
yield return new WaitForSeconds(interval);
}
As alternative, which i do not recommend, you can start the coroutine again at the end.
....
yield return new WaitForSeconds(interval);
StartCoroutine(SpawnWaves(spawnInterval));
A coroutine uses a enumerator for running the above code. Basically the compiler creates a background class which implements the IEnumerator
interface. Jon Skeet explains it very well here.
Upvotes: 4