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.

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)

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;
}

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>