I have this codes but when I run, sometimes the gameobjects spawn at the same time and at the same place. I need help.
public Transform player;
public float maxTime;
public float minTime;
public int valuespawn = 2;
public GameObject[] spawnPrefabs;
public Transform[] spawnLocation;
int currentPrefabs;
int currentLocation;
void Start () {
spawner ();
}
void Update(){
if (player.transform.position.x > 40)
CancelInvoke ();
}
void spawner () {
List<Transform> spawnPoint = new List<Transform> (spawnLocation);
for (int i = 0; i < valuespawn; i++) {
if (spawnPoint.Count <= 0)
return;
currentPrefabs = Random.Range (0, spawnPrefabs.Length);
currentLocation = Random.Range(0, spawnPoint.Count);
Transform pos = spawnPoint [currentLocation];
spawnPoint.RemoveAt (currentLocation);
Instantiate (spawnPrefabs [currentPrefabs], pos.position, pos.rotation);
Invoke ("spawner", Random.Range (minTime, maxTime));
}
}
Try this:
public class Spawner : MonoBehaviour
{
public Transform[] spawnPoints;
public GameObject[] prefabs;
public float minTime, maxTime;
public int numberOfSpawns = 2;
private float timer = 0f;
private int lastSpawnPointIndex = -1;
private void Update()
{
if (timer <= 0f)
{
SpawnItems();
ResetTimer();
}
timer -= Time.deltaTime;
}
private void SpawnItems()
{
for (int i = 0; i < numberOfSpawns; i++)
{
Transform spawnPoint = GetNextSpawnPoint();
GameObject prefab = prefabs[Random.Range(0, prefabs.Length)];
Instantiate(prefab, spawnPoint);
}
}
private Transform GetNextSpawnPoint()
{
// We want a random index from the error, but not the same as last time.
// So we at least more one index further and stop one index before the last.
// The % operator loops back to the beginning of zero, if the index overshoots the array length.
int index = (lastSpawnPointIndex + Random.Range(1, spawnPoints.Length - 1)) % spawnPoints.Length;
lastSpawnPointIndex = index;
return spawnPoints[index];
}
private void ResetTimer()
{
timer = Random.Range(minTime, maxTime);
}
}
public class SomeOtherScript
{
public Spawner spawner;
public Transform player;
private void Update()
{
// Style tip:
// This logic of disabling the spawner should go in a separate class
// because the spawner should only deal with spawning objects.
if (player.position.x > 40)
spawner.enabled = false;
}
}
It’s not entirely clear to me what behavior you are trying to achieve, but I would create a simple timer which ticks down a fixed amount of time and then changes its next timer value via Random.Range. When the timer is up, we can spawn the desired number of objects.
To avoid spawning at the same location twice, you pick an index, which you haven’t used last time (or a list of multiple indices to avoid alternating between two values randomly).
Disclaimer: I couldn’t test this code, so it might have mistakes, but I’m sure it can point you in the right direction. 