Spawning limited GameObjects at a specific position not working
Hi,
I'm trying to spawn in the scene 7 GameObjects from an array of prefabs. Currently the script spawns 7 object from the array (the 7 GameObjects are the same one all the time) and the every GameObject is spawn in the same position as the other ones. What I'm trying to achive is to pick up 7 GameObjects from the array (it can not be any one duplicated) and spawn in scene at the same position that GameObject prefab has. This is the script I'm using:
public GameObject [] luggageDestiny;
public Vector3 destinyValues;
void Start () {
GameObject destinySpawn = luggageDestiny [Random.Range (0, luggageDestiny.Length)];
for (int j = 0; j < luggageDestiny.Length; j++) {
GameObject clone = (GameObject)Instantiate(destinySpawn, destinySpawn.transform.position, destinySpawn.transform.rotation);
luggageDestiny [j] = clone;
}
I would like to help you, but i have to clarify some things.
So, you have an array of prefabs, called luggageDestiny. It has a lot of prefabs assigned to it, more than 7 (i assume). You want to pick 7 unique prefabs from this array, and place it in the scene. (Correct me, if i am wrong).
Where do you want to spawn these objects? Every prefab has it's own position?
Hi $$anonymous$$oenigX3, thanks for helping :D
Yes, I have the luggageDestiny Array with 50 prefabs, and I want to pick 7 random prefabs from the array (prefabs can not be repeated, so I have 7 diferent prefabs) and place them in the scene.
I want to place each one in a specific position in the scene, and the 7 positions for the prefabs is always going to be the same (example: prefab1 placed at position 1, 1, 1; prefab2 at 2, 2, 2)
Answer by KoenigX3 · Jan 06, 2017 at 02:35 PM
The solution looks something like this:
using System.Collections.Generic;
public GameObject[] luggageDestiny;
GameObject[] spawnedObjects;
void Start ()
{
spawnedObjects = new GameObject[7];
List<int> usedIndices = new List<int>();
for(int j = 0; j < spawnedObjects.Length; j++)
{
int randomIndex = Random.Range(0, luggageDestiny.Length);
while(usedIndices.Contains(randomIndex)) randomIndex = Random.Range(0, luggageDestiny.Length);
GameObject clone = (GameObject) GameObject.Instantiate(luggageDestiny[randomIndex], luggageDestiny[randomIndex].transform.position, luggageDestiny[randomIndex].transform.rotation);
spawnedObjects[j] = clone;
usedIndices.Add(randomIndex);
}
}
The code first creates an array of gameobjects, named 'spawnedObjects'. This will contain the objects you are spawning, so you can use them later if you want.
The for loop executes 7 times. Each time it generates a random index from 0 to the length of the prefabs (50 in this case). If we have already spawned a prefab with that index, it generates a new one. (Note: this method is not very efficient if the luggageDestiny array has 10 elements, but in this case, it will be fine.)
After this, the code will instantiate the gameobject with the prefab's original position and rotation. If you want to place them according to their index in the luggageDestiny array, you should use this line instead:
GameObject clone = (GameObject) GameObject.Instantiate(luggageDestiny[randomIndex], new Vector3(randomIndex, randomIndex, randomIndex), luggageDestiny[randomIndex].transform.rotation);
Or if you want to place them according to their line number (so the 1th spawned prefab will spawn to new Vector3(1, 1, 1), the 2nd will spawn to new Vector3(2, 2, 2), etc.), you should use this line:
GameObject clone = (GameObject) GameObject.Instantiate(luggageDestiny[randomIndex], new Vector3(j, j, j), luggageDestiny[randomIndex].transform.rotation);
The rotation can be modified as well. Right now, every prefab will spawn with the original rotation it has. You can use the same methods to apply rotation based on their index or line number, but you have to use a new method:
GameObject clone = (GameObject) GameObject.Instantiate(luggageDestiny[randomIndex], new Vector3(j, j, j), Quaternion.Euler(j, j, j));
(EDIT: i've forgot to mention that you have to insert 'using System.Collections.Generic' before the name of the class)
Hi $$anonymous$$oenigX3, thanks for your answers :D
Just a few questions:
1) If I use System.Collections.Generic I have to use System.Collections too? What's the diference between them?
2) $$anonymous$$aybe it has been my fault, but I want to spawn the GameObjects from the array in 7 diferent specific positions in scene. Each position makes taht the GameObject has a specific rotation depending in which position it is spawned. This are the 7 positions and rotations:
Position 1: -3.75, 0.464, -3.75
Rotation 1: 0, -135, 0
Position 2: -5.42, 0.464, 0
Rotation 2: 0, -90, 0
Position3: -3.75, 0,464, 3.75
Rotation3: 0, -45, 0
Position4: 0, 0.464, 5.42
Rotation4: 0, 0, 0
Position 5: 3.75, 0.464, -3.75
Rotation5: 0, 135, 0
Position6: 5.42, 0.464, 0
Rotation6: 0, 90, 0
Position7: 3.75, 0.464, 3.75
Rotation7: 0, 45, 0
3) In case I just want to change the names of the 7 GameObject from the luggageDestiny Array to 7 diferent names (names can not be repeated) from an Array of 50 strings how can it be done?
System.Collections and System.Collections.Generic are different namespaces. They contain different classes and interfaces for making collections. System.Collections is added to every script by default, however System.Collections.Generic is not - this namespace contains the List (which has dynamic size in opposition with the arrays)
If you want to assign position and rotation to the gameobject from an array, you can create a 'positionArray' and a 'rotationArray' and fill it with the data. Then use them with the index:
GameObject clone = (GameObject) GameObject.Instantiate(luggageDestiny[randomIndex], positionArray[j], rotationArray[j]);
If you want to assign 7 different names, you can create a new list again to store used names:
using System.Collections.Generic;
public GameObject[] luggageDestiny;
public names[] objectNames;
GameObject[] spawnedObjects;
public Vector3[] positions;
public Quaternion[] rotations;
void Start ()
{
spawnedObjects = new GameObject[7];
List<int> usedIndices = new List<int>();
List<int> usedNames = new List<int>();
for(int j = 0; j < spawnedObjects.Length; j++)
{
int randomIndex = Random.Range(0, luggageDestiny.Length);
int randomName = Random.Range(0, objectNames.Length);
while(usedIndices.Contains(randomIndex)) randomIndex = Random.Range(0, luggageDestiny.Length);
while(usedNames.Contains(randomName)) randomName = Random.Range(0, objectNames.Length);
GameObject clone = (GameObject) GameObject.Instantiate(luggageDestiny[randomIndex], positions[j], rotations[j]);
spawnedObjects[j] = clone;
clone.name = objectNames[randomName];
usedIndices.Add(randomIndex);
usedNames.Add(randomName);
}
}
You have to assign positions and rotations to the arrays.
Your answer
Follow this Question
Related Questions
How can i Instantiate gameobject in array 0 Answers
Game Object doesn't instantiate at Mouse Position 3 Answers
Destroy Instantiate is not working 0 Answers