Im doing a simple Quiz game and I needed a way to get unique random numbers, so I can play the questions in a random order without repeating them. Found the code.
private int maxNumbers = 6;
private List<int> uniqueNumbers;
private List<int> finishedList;
void Start ()
{
uniqueNumbers = new List<int>();
finishedList = new List<int>();
GenerateRandomList();
}
public void GenerateRandomList()
{
for (int i = 0; i < maxNumbers; i++)
{
uniqueNumbers.Add(i);
}
for (int i = 0; i < maxNumbers; i++)
{
int ranNum = uniqueNumbers[Random.Range(0, uniqueNumbers.Count)];
finishedList.Add(ranNum);
uniqueNumbers.Remove(ranNum);
}
//Just to see them in the console
foreach (int data in finishedList)
{
Debug.Log(data);
}
}
The problem here is that the random numbers appear all in once. I need one number at a time and the next randomization just start when I want to, by pressing a button or whatever.
But that’s just the way I feel I can do. For sure there’s a way to do with the numbers all in once in the list.
They are appearing all at once because youre iterating through every number in those for loops. Youre just shuffling th around, which is pointless. Just grab a random one from the list, use it, then remove it. No need for a second List unless youre reusing the questions.
this function would shuffle a list: public List<int> mix(List<int> n){ List<int> r = new List<int> (); while (n.Count>0) { int i = Random.Range(0,n.Count); r.Add(n*);* * n.RemoveAt(i);* * }* * return r;* * }* but even easier, why not just randomly pick a number from your list and remove it?
int PickAndRemoveOneRandom()
{
int randomNum = Random.Range(0, myList.Count); //Pick one random number based on total numbers.
int theNumber = myList[randomNum]; //store the number
myList.Remove(randomNum); //Remove number so it cant be used again.
return theNumber; //return the number
}
Then use the method in your code
int theNumber = PickAndRemoveOneRandom();
Or onClick event on a Unity UI Button → PickAndRemoveOneRandom() and add your " //do stuff code" in the function instead of returning an int
Options:
You could pass the list as parameter: void myMethod(List myList) { }
You could make this support generic types (return & remove ANY type from any List, insuring uniqueness
Keep used numbers in a second List (just add one line before return. usedNumberList.Add(theNumber)
To create the list, you could simply use Unity editor. public List myQuestions = new List() Create a gameobject, attach script. In the Inspector add elements to the List, type in your questions, and save them as prefab Gameobjects.
I didn't try but I guess it wouldn't, I think that the problem is connected to the motion tracking engine. I am a complete beginner and I can't write script, that's why I used the template and the already existing interface. If the problem is not solved in this thread, I'll try to work with an experienced user. If you have other ideas though, please don't hesitate to tell me! Thanks!
This is preety old but I was looking for an answer to the same question and I ended writing an algorithm my self. Seems to work preety well.
//"from" and "to" are inclusive
public List<int> GenerateRandomIntegerList(int from, int to)
{
List<int> numbersDone = new List<int>();
while (true)
{
int i = Random.Range(from, to + 1);
bool isNew = true;
foreach (int num in numbersDone)
{
if (num == i)
{
isNew = false;
}
}
if(isNew)
{
numbersDone.Add(i);
if(numbersDone.Count == to + 1)
break;
}
}
return numbersDone;
}
I think realistically you're going to have delve into code to try and resolve this issue. There could be so many things going wrong here that I'm pretty sure it'll need to be looked into by a C# programmer. You could either enlist the help of an experienced programmer, or if the Bridge Engine is designed to be used by artists, you could contact the support team for that software and see if they can help. It doesn't at first glance seem to be a problem with Unity itself (although I'm prepared to be proven wrong on that of course!).
Just for the sake of completeness, since all the other answers seem to be pretty good already, but I usually do this using a Set structure (HashSets of int in particular).
–
If you know your numbers beforehand: Here’s some pseudo-code:
- Let there be an empty Set of type Set of Integers called 'SortitionSet'
- Let there be an Integer Array containing the numbers we want to Sortition called 'IntegersArray'
Generate the SortitionSet:
While(Length of IntegersArray > 0)
Let there be an auxiliary variable which receives a the resulting element from the deletion of the first element of the array called 'aux'
Try to insert aux into SortitionSet (It should return false in case of a repeated number)
In case the insertion was successful continue, otherwise throw exception
Return SortitionSet
Give a Random Number from the Set by Removing it:
Return SortitionSet.Remove(Random Index)
</end>
–
If you don’t know your numbers beforehand:
Here’s some pseudo-code:
<begin/>
- Let there be an empty Set of type Set of Integers called 'SortitionSet'
- Let there be a positive Integer number greater than zero called 'AmountOfNumbersToGenerate'
Then:
While(AmountOfNumbersToGenerate > 0)
Let there be an auxiliary variable which receives a randomly generated number called 'aux'
Try to insert aux into SortitionSet (It should return false in case of a repeated number)
In case the insertion was successful reduce AmountOfNumbersToGenerate by 1
Return SortitionSet
</end>
–
Hope this helps someone! Cheers!
Thank you very much! If anything comes up I'll let you know in this thread!
They are appearing all at once because youre iterating through every number in those for loops. Youre just shuffling th around, which is pointless. Just grab a random one from the list, use it, then remove it. No need for a second List unless youre reusing the questions.
– CarterG81