- Home /
Wait For Seconds Instantiate Inside For Loop
This scrip is suppose to instantiate some prefabs after waiting for a few seconds, but the scrips just spits all of the prefabs out after only waiting once. What do i need to work on.
public GameObject collectablePrefab;
public Vector3 SpawnThinger;
private int collectablePrefabCount;
void Start ()
{
collectablePrefabCount = 3;
for (int i = 0; i <= collectablePrefabCount; i++)
{
Invoke("spawnCollectables", 2f);
}
}
void spawnCollectables()
{
float x, y, z;
x = Random.Range(-9f/2, 9f/2);
y = Random.Range(.5f, 1f);
z = Random.Range(-9f/2, 9f/2);
SpawnThinger = new Vector3(x, y, z);
Instantiate(collectablePrefab, SpawnThinger, Quaternion.identity);
Debug.Log(x);
}
And the waiting time is supposed to be 2 seconds between each instantiation?
Answer by TSI25 · Oct 13, 2017 at 06:01 PM
The problem is that all of those invokations are started at the same time from that for loop, and so they all end at the same time. you will want to use a coroutine instead of invoke. that will look like this
IEnumerator Start()
{
collectablePrefabCount = 3;
for (int i = 0; i <= collectablePrefabCount; i++)
{
yield return new WaitForSeconds(2f);
spawnCollectables();
}
}
I have a habit of putting protected in front of my function I think that just slipped in there XD leaving it private would be more than reasonable.
the main reason to make it protected would just be to make it inheritable by sub classes
$$anonymous$$ake two classes, one which derives from $$anonymous$$onoBehaviour, second which derives from new base class, try having private and protected.
This works the way i need it to, thank you! But for clarification, the for-loop started all of the spawns at the same time? Why exactly did it only the waiting period only occur once in a for-loop that request the waiting 4 times for my understanding. Thanks again by the way! Big smiles !!
Answer by Bunny83 · Oct 13, 2017 at 07:00 PM
Another way without a coroutine would be this:
void Start ()
{
collectablePrefabCount = 3;
for (int i = 0; i <= collectablePrefabCount; i++)
{
Invoke("spawnCollectables", 2f + 2f * i);
}
}
So you basically start the 4 delayed methods all at the same time but with different delays. 2, 4, 6 and 8 seconds. If it's just a few method calls this would work fine. However if you have many things to chain up it's better to use a coroutine.
This works as well, but i don't understand why, could you explain to me what you mean by
"2, 4, 6 and 8 seconds."
and
by that you mean having a large sample size for my collectible correct? oh and, LOL i said look at that, i spelled collectible wrong. collectable. S$$anonymous$$DH"However if you have many things to chain up it's better to use a coroutine."
This for loop:
collectablePrefabCount = 3;
for (int i = 0; i <= collectablePrefabCount; i++)
{
Invoke("spawnCollectables", 2f + 2f * i);
}
Is equivalent to:
Invoke("spawnCollectables", 2f);
Invoke("spawnCollectables", 4f);
Invoke("spawnCollectables", 6f);
Invoke("spawnCollectables", 8f);
So you start 4 delayed Invoke calls at the same time but each with a different delay. The term 2f + 2f * i
will be "2" when "i == 0" and will be "4" when "i == 1" and so on.
When your "collectablePrefabCount" is high you would start a seperate invoke call for each one. The invoke call has to be stored and managed by Unity. So if you want to create 100 it wouldn't make much sense to start 100 seperate invoke calls distributed over time. It would make more sense to use a coroutine and just work through them sequencially.
I just wanted to present another way.
Very nicely put, i understand a lot more about how that works, thank you.