The easiest solution is to use a second List. Fill it with the same elements from your original list and just work with the duplicate list. So don’t touch the original list at all.
Though RemoveAt with a random index may not perform so well. While it’s basically for free to remove the last element in a list, removing the first is quite expensive as all remaining elements have to be moved one spot. Since the order of the elements do not matter you can simply replace the item you just used with the element from the last index and remove the last index. This is an O(1) operation. Of course the order of the elements would change the more elements you remove, but since you pick a random one anyways it doesn’t matter.
Another way, if you don’t want to use a seperate list is to simply scramble the whole list and use an index counter what your last picked element was. So you can just use the elements one after another since the list is already in a random order. You can use the Fisher - Yates shuffle to shuffle the list. Keep in mind that this would shuffle your original list.
The two list approach basically works like this:
public List<GameObject> BadgesGameInventory;
private List<GameObject> workingList = new List<GameObject>();
private void ResetWorkingList()
{
workingList.Clear();
workingList.AddRange(BadgesGameInventory);
}
private GameObject GetRandomBadge()
{
// if the working list is empty, just refill it with all the elements
if (workingList.Count == 0)
ResetWorkingList();
int index = Random.Range(0, workingList.Count);
GameObject res = workingList[index];
// remove picked element by replacing with last element
workingList[index] = workingList[workingList.Count-1];
// remove last element
workingList.RemoveAt(workingList.Count-1);
return res;
}
This method will return a random prefab reference each time you call it. It will not repeat the same twice unless you used up all elements in which case it starts over.
So you can simply do this in Start
for (int i = 0; i < 6; i++)
{
Instantiate(GetRandomBadge(), new Vector3(-4f + i * 1.5f, -2.9f, 0), Quaternion.identity);
}
The shuffling approach is probably the simplest one once you have the shuffling implemented. Each time you run through all elements (or when you want to reset the picking algorithm) you just reshuffle the list and reset the counter / index. There are endless example implementation of the Fisher Yates shuffle on UnityAnswers.
The basic layout for the shuffling is this:
public List<GameObject> BadgesGameInventory;
private int index = 0;
void StartOver()
{
ShuffleList(BadgesGameInventory);
index = 0;
}
private GameObject GetRandomBadge()
{
if (index >= BadgesGameInventory.Count)
StartOver();
// just return the element at index and increment index by 1 after that.
return BadgesGameInventory[index++];
}
Of course both implementations here do assume that BadgesGameInventory is not empty.