- Home /
What is a good method for tracking an array of different times?
Hello, I am trying to implement a spawner object and am looking for some advice about the best approach in dealing with multiple timers. Here is a stripped down example of what I am doing, in c#:
[System.Serializable]
public class SpawnerList
{
public Transform objectToSpawn;
public float secondsUntilNextSpawn = 1;
}
public class Spawner : MonoBehaviour
{
public SpawnerList[] spawnerList;
}
So in the inspector you have an array of SpawnerList objects, each having a prefab and a spawn time. What would be the best approach to dealing with tracking those different times, and spawning the different prefabs at the right times?
Answer by Bunny83 · Jan 02, 2012 at 03:17 AM
If each "SpawnerList"-item (which should have a singular name like SpawnItem) should be spawned independently, just start a seperate coroutine for each item.
edit: changed my example
[System.Serializable] public class SpawnItem { public Transform objectToSpawn; public float secondsUntilNextSpawn = 1; }
public class Spawner : MonoBehaviour { public SpawnItem[] spawnList; IEnumerator SpawnLoop(SpawnItem Item) { while(true) // spawns infinite { Instantiate(Item.objectToSpawn); yield return new WaitForSeconds(Item.secondsUntilNextSpawn); } } void Start() { foreach (SpawnItem I in spawnList) StartCoroutine(SpawnLoop(I)); } }
Or which is propably much simpler, attach as many scripts as needed to a GameObject. Since every item works on it's own just create a MonoBehaviour which handles a single object and just attach as many you need:
public class Spawner : MonoBehaviour
{
public Transform objectToSpawn;
public float secondsUntilNextSpawn = 1;
IEnumerator Start()
{
while(true) // spawns infinite
{
Instantiate(objectToSpawn);
yield return new WaitForSeconds(secondsUntilNextSpawn);
}
}
// If you want to stop the spawn loop when the script get disabled, just add this:
void OnDisable()
{
StopAllCoroutines();
}
}
Thank you, I like this as it has increased my understanding of coroutines! For some reason I thought calling the same method as a coroutine multiple times would result in only one coroutine. Now I know better.
Answer by Rod-Green · Jan 02, 2012 at 04:09 AM
Start a coroutine inside each object...
[System.Serializable]
public class SpawnerItem
{
public Transform objectToSpawn;
public float m_spawnDelay = 1;
Spawner m_spawner;
bool m_canRun;
public void Start(Spawner p_spawner)
{
m_spawner = p_spawner;
m_canRun = true;
p_spawner.StartCoroutine(SelfRun());
}
public void Stop()
{
m_canRun = false;
}
IEnumerator SelfRun()
{
while(m_canRun)
{
yield return new WaitForSeconds(m_spawnDelay);
Debug.Log("Im running every..." + m_spawnDelay);
}
}
}
public class Spawner : MonoBehaviour
{
public SpawnerItem[] m_spawnerItems;
void Start()
{
if(m_spawnerItems == null)
return;
foreach(SpawnerItem eachItem in m_spawnerItems)
{
if(eachItem == null)
continue;
eachItem.Start(this);
}
}
}
This would work when you pass-in a $$anonymous$$onoBehaviour instance, because StartCoroutine is a member function of $$anonymous$$onoBehaviour.
@Bunny83 oh of course.. :S silly me O$$anonymous$$ tweaked a little..
Thanks, this is very interesting. To my untrained eye it seems a more "correct" solution to have the SpawnerItem deal with its coroutine as you demonstrate here. I used Bunny83's as it fit more easily into what I had, so I guess I have to mark that as correct. But this is good too, thank you.
Your answer
Follow this Question
Related Questions
How to add a delay to a bomb explostion 1 Answer
How to make reverse countdown timer in unity? 1 Answer
jump timer 1 Answer
Increase as timer decreases 1 Answer
Are there any performance differences between a timer and using Invoke? 1 Answer