How would I implement a random spawn timer into a list based spawn system?
Currently I'm spawning ships to these transforms, which move at random speeds on a single axis and destroy after a set time. What I need is to implement a random spawn timer into the following script to create the illusion of traffic flow, which can be edited in the inspector for performance/density balance.
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
public class Ship_Traffic_Spawner : MonoBehaviour
{
public int numberOfItemsToSpawn = 49; // modifiable in the inspector
public List<Transform> spawnLocations = new List<Transform>();
public List<GameObject> spawnPrefab = new List<GameObject>();
public List<GameObject> spawnClone = new List<GameObject>();
void Start()
{
for (int i = 0; i < numberOfItemsToSpawn; i++)
{
if ((i < spawnPrefab.Count) && (spawnPrefab [i] != null) &&
(i < spawnLocations.Count) && (spawnLocations [i] != null))
{
// this line spawns a prefab at an objects position
spawnClone [i] = Instantiate (spawnPrefab [i], spawnLocations [i].transform.position, Quaternion.Euler (0, 0, 0)) as GameObject;
}
}
}
}
Answer by M-Hanssen · May 11, 2016 at 09:19 AM
I've modified your code to make everything random ;-)
I hope this makes it clear how to use the Random.range method
Notes:
Always try to initialize your variables inside the Awake method
Use capital CamelCase for public variables
Class names with underscores are bad practice, Change it to "ShipTrafficSpawner" if possible
public class Ship_Traffic_Spawner : MonoBehaviour { public int NumberOfItemsToSpawn = 49; // modifiable in the inspector public List<Transform> SpawnLocations; public List<GameObject> SpawnPrefabs; public List<GameObject> SpawnClones; public float MinSpawnDelay; public float MaxSpawnDelay = 1; protected void Awake() { SpawnLocations = new List<Transform>(); SpawnPrefabs = new List<GameObject>(); SpawnClones = new List<GameObject>(); } protected void Start() { StartCoroutine(SpawnCoroutine()); } protected IEnumerator SpawnCoroutine() { for (int i = 0; i < NumberOfItemsToSpawn; i++) { // Get a random delay float delay = Random.Range(MinSpawnDelay, MaxSpawnDelay); // Get a random spawn location Transform spawnLocation = SpawnLocations[Random.Range(0, SpawnLocations.Count)]; // Get a random prefab to spawn GameObject spawnPrefab = SpawnPrefabs[Random.Range(0, SpawnPrefabs.Count)]; // Wait for the delay yield return new WaitForSeconds(delay); // Spawn the random prefab at a random location SpawnClones.Add((GameObject)Instantiate(spawnPrefab, spawnLocation.position, Quaternion.Euler(0, 0, 0))); } } }
Now nothing works...
ArgumentOutOfRangeException: Argument is out of range. Parameter name: index System.Collections.Generic.List`1[UnityEngine.Transform].get_Item (Int32 index) (at /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Collections.Generic/List.cs:633) Ship_Traffic_Spawner+c__Iterator0.$$anonymous$$oveNext () (at Assets/Ship_Scripts/Ship_Traffic_Spawner.cs:33) UnityEngine.$$anonymous$$onoBehaviour:StartCoroutine(IEnumerator) Ship_Traffic_Spawner:Start() (at Assets/Ship_Scripts/Ship_Traffic_Spawner.cs:23)
You will have to fill the SpawnLocations
and SpawnPrefabs
in your inspector of course!
I filled them, but on play all assigned prefabs/transforms disappear.
Answer by juippi112 · May 10, 2016 at 06:38 PM
Maybe change the Start function into an IEnumerator. Then you could create a while loop like this:
int x = 0;
while(x < numberOfItemsToSpawn)
{
x++;
//spawn a clone to some spawnpoint.
yield return new WaitForSeconds(Random.Range(minDelay, maxDelay));
}
Now just remember to add public float minDelay = .5f, maxDelay = 1f.