- Home /
Make Random.range to not repeat numbers
I have to spawn different platforms and it's crucial that no two platforms get repeated. What I mean is, random.range should not get two simultaneous numbers same. Here's the code
public class PlatformSpawner : MonoBehaviour {
public GameObject RBigPlatformRight;
public GameObject RBigPlatformLeft;
public GameObject RSmallPlatformRight;
public GameObject RSmallPlatformLeft;
public GameObject RMiddlePlatform;
public GameObject YBigPlatformRight;
public GameObject YBigPlatformLeft;
public GameObject YSmallPlatformRight;
public GameObject YSmallPlatformLeft;
public GameObject YMiddlePlatform;
private bool shouldSpawn = false;
public float len;
public float sec;
void Start () {
StartSpawn ();
}
void Update () {
}
public void StartSpawn(){
shouldSpawn = true
StartCoroutine("SpawnObj");
}
public void StopSpawn() {
shouldSpawn = false;
}
public IEnumerator SpawnObj ()
{
while (shouldSpawn) {
int i = Random.Range (1,16);
GameObject obj;
if (i == 1) {
obj = RBigPlatformLeft;
} else if (i == 2) {
obj = RBigPlatformRight;
} else if (i == 3) {
obj = RMiddlePlatform;
} else if (i == 4) {
obj = RSmallPlatformLeft;
} else if (i == 5) {
obj = RSmallPlatformRight;
} else if (i == 6) {
obj = YBigPlatformRight;
} else if (i == 7) {
obj = YMiddlePlatform;
} else if (i == 8) {
obj = YSmallPlatformLeft;
} else if (i == 9) {
obj = YSmallPlatformRight;
} else if (i == 10) {
obj = YBigPlatformLeft;
}
// removed extra platforms for simplicity
Instantiate (obj, new Vector3 (transform.position.x * len, transform.position.y), Quaternion.identity);
yield return new WaitForSeconds (sec);
}
}
}
Thank you!
You probably want to shuffle an array of numbers.
This will shuffle a list / array in place:
// Shuffles the given iterable in place.
private void Shuffle<T> (IList<T> list)
{
// Create an RNG to use here. We need to use System.Random to not
// accidentally make a UnityEngine.Random instance
System.Random rng = new System.Random ();
int n = list.Count;
while (n > 1) {
n--;
int k = rng.Next (n + 1);
T value = list [k];
list [k] = list [n];
list [n] = value;
}
}
This is what you will call to get a randomized order for your platforms:
// Return a shuffled array of integers from a given $$anonymous$$ and max, both inclusive.
private int[] CreateRandomArray (int $$anonymous$$ = 1, int max = 16)
{
// Create a list from your bounds
int[] platformOrder = new int[max - $$anonymous$$ + 1];
// Add your values in the natural order
for (int k = 0; k < platformOrder.Length; k++) {
platformOrder [k] = k + $$anonymous$$;
}
// Then shuffle them with the extension above
this.Shuffle<int> (platformOrder);
// And return your shuffled order
return platformOrder;
}
When your coroutine SpawnObj starts, you will create a new array with this function and use it with your While loop. I imagine your implementation will look something like this:
public IEnumerator SpawnObj ()
{
//Create a new spawn order
int[] spawnOrder = this.CreateRandomArray (1, 16);
// Then go through for however many platforms we have
for (int k = 0; k < spawnOrder.Length; k++) {
// Preserve the original functionality
if (this.shouldSpawn == false)
break;
// Current platform to use
int i = spawnOrder [k];
//
// [Your other stuff]
//
yield return new WaitForSeconds (sec);
}
}
Nobody said it yet, so I'll add a google suggestion: Shuffle Bag.
Answer by Konomira · Dec 20, 2017 at 10:54 PM
Something similar to this would work.
using System.Collections.Generic;
List<int> list = new List<int>(); // Declare list
for (int n = 0; n < 10; n++) // Populate list
{
list.Add(n);
}
int index = Random.Range(0, list.Count - 1); // Pick random element from the list
int i = list[index]; // i = the number that was randomly picked
list.RemoveAt(index); // Remove chosen element
// Loop lines 10-13 as many times as needed
This may or may not be more efficient than @Larry-Dietz answer as this negates the need to pick a random number more than once per cycle, however it does remove elements from the list which is possibly a more expensive process. If anyone does know which is more efficient I would love to know!
If you want no duplication, then @$$anonymous$$onomira answer would be more efficient, I believe. If however, you want duplication, just not two of the same back to back, then his answer wont accomplish that.
It would be better If I have no dublication at all! Thank you so much @Larry-Dietz and @$$anonymous$$onomira for the quick response!
Thought this might be helpful to someone. Another way to accomplish the same thing is to fill a List with whatever you want to randomize, then call this extension method (Shuffle):
public static class ListExtensions
{
private static readonly Random Random = new Random();
public static void Shuffle<T>(this IList<T> list)
{
int n = list.Count;
while (n > 1)
{
n--;
int k = Random.Next(n + 1);
T value = list[k];
list[k] = list[n];
list[n] = value;
}
}
}
So for ints, you could do this:
List<int> randomInts = new List<int>();
for(int i = 0; i < 100; i++)
{
randomInts.Add(i);
}
randomInts.Shuffle();
Pretty straightforward usage. Typically I use this to shuffle lists of vectors, etc.
THANK YOU so much for this! I've got it working but how can I make an if statement for when all the numbers have been picked? edit. I'm replying to konomira. i know this is very old and a shot in the dark but hey its worth the shot at least!
Answer by Larry-Dietz · Dec 20, 2017 at 06:33 PM
First thing that pops into my head would be to create a list of ints, then loop through selecting a random number, compare the random number to the list, if it is not there, add it. If it is already in the list, select a new random number and repeat. If you only want to stop 2 of the same back to back, but still allow duplication, then just check the last entry in the list instead of checking if the list contains the new random number.
Once your list is built out to the length you need, then use the list to make your selection for the platform, instead of a random number.
Hope this helps, -Larry
Answer by Maynk · Dec 14, 2020 at 12:32 PM
Hey Check This Because I Already Put An Answer Code in them https://answers.unity.com/questions/786800/random-positions-without-repeating.html?childToView=1796849#answer-1796849
I Hope You Got AN Answer And You Given A Solution, Try Them
Your answer
Follow this Question
Related Questions
How to know what random number is chosen 2 Answers
Selection list from Array Unity - Random - GameObjects array 1 Answer
My sprite doesn't render on scene view and game view 2 Answers
pick a random int with the value of 1 from an array 2 Answers
How do you get different random numbers for each object array? 1 Answer