- Home /
Prevent object from spawning at a spawn point twice in a row?
I have a set of spawn points and an object that I want to spawn from a random spawn point every second. I've used the InvokeRepeating function to make this work. But now, I want to modify the code a little bit. I don't want the the object to be spawned from the same spawn point twice in a row.
Let's say I have 5 spawn points: A, B, C, D, and E. When InvokeRepeating runs, the object is spawned randomly from spawn point C. So when InvokeRepeating runs again, I don't want the object to spawn at spawn point C. It has to randomly pick another spawn point. I don't want the object to spawn at at a particular spawn point twice in a row.
Here my code:
 void Start () 
     {
         GameObject[] SP = GameObject.FindGameObjectsWithTag ("spawnPoint");
         spawnPoints = new Transform[SP.Length];
         for(int i=0; i < SP.Length; i++)
         {
             spawnPoints[i] = SP[i].transform;
         }
 
         InvokeRepeating("SpawnObject", spawnTime, spawnTime);    
     }
 
 void SpawnObject()
     {
         int spawnPointIndex = Random.Range(0,spawnPoints.Length);
         Instantiate(theObject, spawnPoints[spawnPointIndex].position, spawnPoints[spawnPointIndex].rotation);
     }
Any idea what I can add to my code so solve this?
Answer by Jessespike · Jul 28, 2016 at 06:30 PM
If you are only concerned about the next and previous spawn points, then you can store the last spawn point index and find a new index that doesn't match the previous one.
 int prevSpawnIndex = -1;
 void SpawnObject()
 {
     int spawnPointIndex;
     do {
         spawnPointIndex = Random.Range(0,spawnPoints.Length);
     } while (prevSpawnIndex == spawnPointIndex && spawnPoints.Length > 1);
     prevSpawnIndex = spawnPointIndex;
     Instantiate(theObject, spawnPoints[spawnPointIndex].position, spawnPoints[spawnPointIndex].rotation);
 }
I totally forgot about this. Sorry for taking so long.
Answer by ScaniX · Jul 28, 2016 at 06:42 PM
Something like this should work. It is a playlist approach, so each position is used exactly once, before it starts over again.
Note, that I haven't tested this as I wrote it down here, outside of Visual Studio, so there can be some typos. :)
 private List<int> pendingSpawnPoints = new List<int>();
 private void CreateSpawnList(int avoidedStartIndex) {
     List<int> tempList = new List<int>();
     for (int i=0; i<spawnPoints.Length; i++)
          tempList.Add(i);
     pendingSpawnPoints.Clear(); // it usually already is empty
     for (int i=0; i<spawnPoints.Length; i++) {
         int idx = Random.Range(0, tempList.Count);
         if (tempList[idx] == avoidedStartIndex)
             idx = (idx + 1) % tempList.Count;
         pendingSpawnPoints.Add(tempList[idx]);
         tempList.RemoveAt(idx);
     }
 }
 void Start () 
  {
      GameObject[] SP = GameObject.FindGameObjectsWithTag ("spawnPoint");
      spawnPoints = new Transform[SP.Length];
      for(int i=0; i < SP.Length; i++)
      {
          spawnPoints[i] = SP[i].transform;
      }
      CreateSpawnList(-1);
      InvokeRepeating("SpawnObject", spawnTime, spawnTime);    
  }
 
  void SpawnObject() {
      int spawnPointIndex = pendingSpawnPoints[0];
      pendingSpawnPoints.RemoveAt(0);
      if (pendingSpawnPoints.Count == 0)
          CreateSpawnList(spawnPointIndex);
      Instantiate(theObject, spawnPoints[spawnPointIndex].position, spawnPoints[spawnPointIndex].rotation);
  }
Answer by milanow · Jul 29, 2016 at 12:31 PM
I have encountered the same issue before. I solved it by searching out an algorithm that generate unrepeated number.
Supposing u have five positions Vector3[] genPoints = new Vector3[5];
You can get new positions by int index = Random.Range(0, 5);
And you create another int array
int[] intArr = new int[5]; for(int i = 0; i < 5; ++i) intArr[i] = i
Say index = 3 this time, then swap the value of intArr[3] and intArr[intArr.Count - 1] in intArr. Now you have 0, 1, 2, 4, 3 in intArray
And you got the generate point by genPoints[index]; The key point is next time you should Call index = Random.Range(0, 4) instead of Random.Range(0, 5), Now you only have "0, 1, 2, 4" these four values in intArr that can be accessed by intArr[index]
Then just reduce the random range by one for each time. Pretty simple algorithm but helpful
Your answer
 
 
              koobas.hobune.stream
koobas.hobune.stream 
                       
                
                       
			     
			 
                