I'm trying to create a memory game with 24 cards where you have find the pairs. So, I have the 12 prefab card objects that are supposed to spawn in a random order into a grid. I've searched online and what worked for me was to create the grid using a for loop and Instantiate to spawn the objects in different positions (rows and columns) till I get the 24 objects. The thing is I cannot find a way to spawn the 12 prefabs list and a copy of each.
I've tried searching for a different method or how to Instantiate a whole list of objects but I've only found how to do it creating an index and Random.Range the list, but this is not what I want because I need all the cards and twice each. This is how my code looks right now.
public class GridManager : MonoBehaviour
{
public int columnLenght;
public int rowLenght;
public float x_Space;
public float y_Space;
public float x_Start;
public float y_Start;
public float z_Start;
public List<GameObject> cardPrefabs;
// Start is called before the first frame update
void Start()
{
for (int i = 0; i < columnLenght * rowLenght; i++)
{
int index = Random.Range(0, cardPrefabs.Count);
Instantiate(cardPrefabs[index], new Vector3(x_Start + (x_Space * (i % columnLenght)), y_Start + (-y_Space * (i / columnLenght)), z_Start + (0)), Quaternion.Euler(270, 0, 0));
}
}
How can I spawn 12 prefabs * 2 in a random order in a grid?
The code you have written is almost there. After you pick and instantiate the next card you can go into the list and remove the card (at the index or the object itself).
int index = Random.Range(0, cardPrefabs.Count);
Instantiate(cardPrefabs[index], new Vector3(x_Start + (x_Space * (i % columnLenght)), y_Start + (-y_Space * (i / columnLenght)), z_Start + (0)), Quaternion.Euler(270, 0, 0));
cardPrefabs.RemoveAt(index);
If you need to reset the game multiple times I would recommend making a copy of the list, to preserve the cards for next time.
Regarding needing each card to be spawned twice, you can just add each card to the list two times. If you want to be lazy like a programmer you can also make the computer do that for you programmatically.
cardPrefabs.Add(cardPrefabs);//only call this once at Start
It's not really important, but you could improve the for loop and make it a bit easier to read by looping thru the x and y of the grid instead of going with a single i and calculating the coordinates every time.
for (int x = 0; x < columnLenght; x++)
{
for (int y = 0; y < rowLenght; y++)
{
int index = Random.Range(0, cardPrefabs.Count);
Instantiate(cardPrefabs[index], new Vector3(x_Start + (x_Space * x), y_Start + (-y_Space * y), z_Start), Quaternion.Euler(270, 0, 0));
cardPrefabs.RemoveAt(index);
}
}