- Home /
Spawn objects (Instantiate) behind hierarchy
Hey dev gurus. I need some help here. As far as I've searched, literally no one has ever asked this question so i'm afraid it's not possible.
I want to spawn random objects but behind each other in the hierarchy. Using this script I can successfully spawn prefabs but they're getting spawned on top of each other. Script: public class SpawnScript : MonoBehaviour {
//prefabs
public GameObject prefab1, prefab2, prefab3, prefab4;
//spawn prefabs every 1s
public float spawnRate = 1f;
//var to set next spawn rate
float nextSpawn = 0f;
//var to contain random value
int whatToSpawn;
// Use this for initialization
void Start () {
}
// Update is called once per frame
void Update () {
if (Time.time > nextSpawn) {
whatToSpawn = Random.Range (1, 5);
//Debug.Log (whatToSpawn); //what spawned?
//spawn based on random value
switch (whatToSpawn) {
case 1:
GameObject FB = Instantiate (prefab1, transform.position, Quaternion.identity) as GameObject;
Debug.Log ("FB");
FB.transform.SetParent (GameObject.FindGameObjectWithTag ("Canvas").transform, false);
break;
case 2:
GameObject FC = Instantiate (prefab2, transform.position, Quaternion.identity) as GameObject;
Debug.Log ("FC");
FC.transform.SetParent (GameObject.FindGameObjectWithTag("Canvas").transform, false);
break;
case 3:
GameObject HC = Instantiate (prefab3, transform.position, Quaternion.identity) as GameObject;
Debug.Log ("HC");
HC.transform.SetParent (GameObject.FindGameObjectWithTag("Canvas").transform, false);
break;
case 4:
GameObject HT = Instantiate (prefab4, transform.position, Quaternion.identity) as GameObject;
Debug.Log ("HT");
HT.transform.SetParent (GameObject.FindGameObjectWithTag("Canvas").transform, false);
break;
}
//set next spawn time
nextSpawn = Time.time + spawnRate;
}
}
}
Here's what happens when I run the code:
Even though 'HT' Spawned in first, it's appearing behind all of the others (the problem):
Any help or alternate suggestions would be highly appreciated. Thanks!
Answer by Harinezumi · Apr 05, 2018 at 02:25 PM
The order in which UI elements are drawn depends on their order in the hierarchy, and the last one is drawn last.
So I think you are looking for Transform.SetAsFirstSibling(). Call it after SetParent()
, and it will become the one on the bottom.
You can also simplify your code with arrays and more appropriate types:
// store your prefabs in an array instead of separately
// also, as they are added to a Canvas, they will have to have a RectTransform, so you can store them as such - which makes it easier to call SetParent() on them
[SerializeField] private RectTransform[] prefabs;
private RectTransform canvas;
private void Start () {
// FindGameObjectWithTag() is slow, so store Canvas so you only look for it once
GameObject canvasObject = GameObject.FindGameObjectWithTag("Canvas");
canvas = canvasObject.GetComponent<RectTransform>();
}
...
{
// this makes sure you always access a valid prefab
whatToSpawn = Random.Range(0, prefabs.Length);
if (prefabs[whatToSpawn] == null) { /* prefab not set, handle it! */ return; }
RectTransform spawnedPrefab = Instantiate (prefabs[whatToSpawn], transform.position, Quaternion.identity);
// the only functionality you lose with arrays is the custom debug message
// but printing the name is more precise anyway:
Debug.Log(prefabs[whatToSpawn].name);
spawnedPrefab.SetParent(canvas, false);
spawnedPrefab.SetAsFirstSibling(); // here the solution to your original question
}
First off, thanks a lot for the answer and help. Greatly Appreciated, Harinezumi! Okay so the line canvas = FindGameObjectWithTag("Canvas"); gave the "doesn't exist in the current context" error so I naturally added "GameObject." behind FindGameObjectWithTag but soon realized that this wouldn't be possible and got the error "Cannot implicitly convert type UnityEngine.GameObject' to
UnityEngine.RectTransform'".
This is probably a basic rookie mistake but i'm learning something new everyday. Thanks!
Oh, right, sorry, that is actually my mistake. FindObjectWithTag()
only returns GameObjects, so it cannot be assigned to the variable canvas
which is of type RectTransform
. Once found, you also need to GetComponent<RectTransform>()
on it.
I will update the answer with the correct line.
Your answer
Follow this Question
Related Questions
getting the object that the running script is attached to 1 Answer
select all objects in the hierarchy of an object 1 Answer
How to create hierarchy menu such as unity hierarchy tab. 0 Answers
Why do I have lots of 'One Shot Audio' objects in my hierarchy? 1 Answer
Swipe direction on an object 0 Answers