- Home /
Simple random spawning system for 10 items without duplicates
Here is a simplified version of what I need:
I have 10 items and I want to spawn 1 item at random every 30 seconds.
I do not want any repeats of active items.
So if 1 item spawned at 30 seconds, then I want a random item from the remaining 9 items to spawn at 1 minute.
If all items are active, then nothing spawns.
If an item is destroyed, then I want it to be added back to the spawnable list.
I have tried using a Random.Range(0, 10) to generate 10 numbers, but I want to remove certain numbers from the list the next time it runs.
So maybe I need a way to generate a Random.Range(0, 10), but somehow remove active numbers from the list?
Answer by tuinal · Jul 09, 2020 at 01:34 AM
Two options; check if you've spawned it already, or pre-generate 10 shuffled numbers.
For the first option, make a List and add what you've spawned, then check if the list .Contains what you're about to spawn, and if so re-roll the dice. This isn't great though as it's a (very much theoretically) infinite loop if the RNG gives you an invalid number infinity times.
So, better to just make an array of int[], populate it with 1-10, then shuffle it in Start(). Draw the next number from the array each time you spawn by incrementing a pointer.
void reshuffle(int[] vals)
{
// Knuth shuffle algorithm :: courtesy of Wikipedia :: and the other Answers post I ripped it from :)
for (int t = 0; t < vals.Length; t++ )
{
int tmp = vals[t];
int r = Random.Range(t, vals.Length);
vals[t] = vals[r];
vals[r] = tmp;
}
}
Answer by Eno-Khaon · Jul 09, 2020 at 03:04 AM
Another way you can approach this is by setting up a list with each option, removing them from the list as they're activated, then returning it to the list after use.
public int valueCount = 10;
List<int> exampleValues;
void Start()
{
exampleValues = new List<int>();
for(int i = 1; i <= valueCount; i++)
{
exampleValues.Add(i);
}
}
public int GetRandomValue()
{
// This randomly grabs from the remaining quantity of possible values
int randomElement = Random.Range(0, exampleValues.Count);
int returnValue = exampleValues[randomElement];
exampleValues.Remove(randomElement);
return returnValue;
}
public void ReturnValue(int valueToReturn)
{
exampleValues.Add(valueToReturn);
}
Your answer
Follow this Question
Related Questions
How to make enemy prefab spawn at random times between 1.0f to 10.0f. 1 Answer
how can i random a spawning but not same gameobject 1 Answer
Random.range multiple instantiations without repetition 1 Answer
random range can stop when the index matches the input and without duplicate question display 2 Answers