How can I spawn a prefab in Unity in a specific position and then delete that value?

I’m making a game, a labyrinth, where you have to collect 10 pickups to win the game. Some of those pickups will be always in the same places, but there are others that will spawn in a random position at the start using a for-loop (previously declared in the code all the possible options). The idea is, when an element has been spawned, the Vector3 containing that position has to be deleted from the List, so it cannot be spawned again in the same place.

I’ve tried doing it with arrays, but I couldn’t delete that value easily, so I decided to try Lists. I’ve found this post aiming to use Lists and giving a solution, but when I’m trying it isn’t working. The pickups aren’t being spawned, but I cannot manage to find the error.

Here’s the code:

public GameObject pointPrefab;

List<Vector3> positions = new List<Vector3>();

public Vector3[] vectorPositions =
{
    new Vector3 (237.05f, 0,- 34.02419f),   // Position 0
    // ... More positions here
    new Vector3 (207.1207f, 0, -74.42f),    // Position 8
};



void Start()
{
    positions.Add(new Vector3(237.05f, 0, -34.02419f));
    // ... More positions here
    positions.Add(new Vector3(207.1207f, 0, -74.42f));


    for (int i = 0; i < 6; i++)
    {
        spawnItem();
    }
}

void spawnItem()
{
    int index = selectRandom();
    Vector3 vector = RemoveAndGet(positions, index);
    Instantiate(pointPrefab, vector, Quaternion.identity);
}

int selectRandom()
{
    return Random.Range(0, positions.Count);
}

public T RemoveAndGet<T>(IList<T> list, int index)
{
    lock (list)
    {
        T value = list[index];
        list.RemoveAt(index);
        return value;
    }
}

Also, you see there’s an array called vectorPositions. I’d like to declare all the Vector3 in that array, and then just use a positions.AddRange(vectorPosition) for assigning all of them to the List (it’s easier to read for me). But that’s also not working (well, I don’t know if it’s working or not because pickups aren’t spawned)

Hope you can help me, I can’t manage to see what’s wrong here.

Thanks!

Answer

There are multiple ways of doing that. E.g. you can simply write

positions = vectorPositions.ToList(); 

or also

positions = new List<Vector3>(vectorPositions);

However, why even create a copy of your array?

You could as well simply make it

public List<Vector3> vectorPositions = new List<Vector3>{ ... };

If you really need to remove items on runtime.


Anyway, you can also way easier generate your 6 random elements using Linq OrderBy with Random.value as sorting criteria and Take in order to take the first 6 consecutive entries from that randomized list

using System.Linq;

...

var sixRandomPositions = vectorPositions.OrderBy(p => Random.value).Take(6);
foreach(var position in sixRandomPositions)
{
    Instantiate(pointPrefab, position, Quaternion.identity);
}

without changing the original vectorPositions.

Leave a Reply

Your email address will not be published. Required fields are marked *