- Home /
Unity freezing on play in "Rrandom number order" function
Hello, I am making survey app in Unity. But have problem with function that are generating numbers from 0 to l-1 in random order, while storing them into list questionOrder.
Problem occurs (Unity freezing on play) when I put one specific condition in if statement bellow.
int l = *someList*.Count; // Length I want my new integer list (questionOrder) to be
int i = 0; // current length of *questionOrder* list
while (i < l)
{
int r = Random.Range(0, l - 1);
int k = 0;
while (i > 0 && k < questionOrder.Count && r != questionOrder[k])
{
k++;
}
if (i == 0 || k == questionOrder.Count) // *k < questionOrder.Count* is problematic
{
questionOrder.Add(r);
i++;
}
}
First I am generating random number r, then with 'nested while' loop checking if generated number exists, if not 'nested while' will end because k == questionOrder.Count (r is compared with every list member, that means r is unique). Then, in IF statement I am checking what was the reason 'nested while' ended (if k == questionOrder.Count then r is unique and will be added to questionOrder list).
If i remove k == questionOrder.Count and set i == 0 to i >= 0 (r does not need to be unique) it works fine.
Note: i > 0 in 'nested while' and i==0 in if are just to work when the questionOrder list is empty.
If what you want is to randomize question order, you can use Fisher–Yates shuffle Algorithm to shuffle an array.
//this is where you have an array as lengt of l
int l = *someList*.Count;
int[] arr = new int[l];
for(int i = 0; i < l; i++){
arr[i] = i;
}
arr = randomize(arr, l); //randomize
//Fisher–Yates shuffle Algorithm
static int[] randomize(int []arr, int n)
{
Random r = new Random();
for (int i = n - 1; i > 0; i--)
{
int j = r.Next(0, i+1);
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
return arr;
}
Hi, thank you for replay!
$$anonymous$$y friend also gave me advice to use this algorithm, so I will definitely use it.
But I still do not understand why my script causes Unity freezing. I know it is very unoptimized, but I tried my script in c# console application and it works fine.
Do you have any idea why it can be problematic for Unity?
Answer by Bunny83 · Apr 27, 2019 at 02:54 AM
With this statement:
int r = Random.Range(0, l - 1);
you can not generate "l" different random numbers since the number count you specify is "l-1". So you will never hit your desired count. This is because Random.Range with integer parameters does exclude the upper limit. So Random.Range(0, 3)
can return 3 different numbers 0, 1 or 2 but never 3.
Since your break condition is i >= l
it will never be reached since the number range you draw from is one less than your desired target amount- So there's no sequence of unique numbers which can do this.
Your line should have looked like this:
int r = Random.Range(0, l);