- Home /
Only instantiate GameObjects with a certain tag from an array
Hi. I'm trying to create a bit of code that instantiates only game objects from an array that are not already active in the game view. What I have at the moment is something that gives a tag to the spawned game object and I'm trying to exclude the ones with a Spawned tag from the random number generator's choices. Here's a some of the code:
void SpawnPerson () {
int randNum = RandomGen();
Vector3 randomPosition = new Vector3
(
Random.Range (boundary.xMin, boundary.xMax),
Random.Range (boundary.yMin, boundary.yMax),
-1.25f
);
if(CubeMover.keepClosed == false)
{
GameObject person = Instantiate
(
personArray[randNum],
randomPosition,
Quaternion.identity
)
as GameObject;
}
personArray[randNum].tag = "Spawned";
}
int RandomGen () {
int i;
i = Random.Range(0, personArray.Length);
return i;
}
}
Answer by supernat · Apr 09, 2015 at 04:37 AM
You can't really do it by using the tag, because you would have to do something like a while loop and continue generating random indices into the personArray until you get to one that doesn't have the tag "Spawned", which would grow exponentially as you continued.
A solution to this problem that I've done myself is to create a List containing the index from 0 to PersonArray.Length-1 as list elements, like this:
List<int> possibleChoices = new List<int>(PersonArray.Length);
for (int i=0; i < PersonArray.Length; ++i)
possibleChoices.Add(i);
Then you can random pick an element from this list:
int index = Random.Range(0, possibleChoices.Count);
possibleChoices.RemoveAt(index);
PersonArray pa = personArray[index];
// Use pa
So possibleChoices gets reduced in size over time but always only contains the unspawned item indices into personArray. You will probably also want to check that possibleChoices.Count is greater than 0 and re-add all indices back to it when it hits count of 0.
That looks superb!
Let's see if I got what it does, trying to clear it up for myself.. So, the for loop adds as many sequential int numbers to the 'possibleChoices' array as there are spaces in the PersonArray.
Then it picks a number between 0 and the length of the possibleChoices array, after which the chosen number is deleted from the amount of possible choices (but it only affects the next round the pick happens as the number has already been chosen) and the picked index number is then used to refer to a slot in the PersonArray.
Yep, that sounds right. It gets a little confusing when you start storing lists of indices that index into a list of ints (but you have a list of objects, so less confusing). :) Just carefully walk through it, and it should make sense when you apply it to your context. I didn't state this clearly, but if you wanted to reduce the set of possible choices every time you instantiate, you would create the possibleChoices list in the Start method. Then check in Update or just after you call possibleChoices.RemoveAt(index) if possibleChoices.Count == 0. If so, re-populate it with everything from PersonArray. Then you have a guaranteed random yet unique item pulled out each time you instantiate, and it refills itself when it gets empty.
Your answer
Follow this Question
Related Questions
Attacking more than one enemy with same tag, but unity only allows one enemy at a time? 2 Answers
Question about FindObjectsOfType 1 Answer
Removing and Adding gameobjects to an array upon collision 1 Answer
How can I make a GameObject face a GameObject with a specific Tag? 1 Answer
Multiple Cars not working 1 Answer