- Home /
Order of instantiated objects in hierachy
I made a test script that looks like this:
using System.Collections; using System.Collections.Generic; using UnityEngine;
public class TestScript : MonoBehaviour {
public bool Test = true;
public bool _Test;
public GameObject TestObject;
public Transform _TestObject;
public GameObject[] TestArray;
void Start()
{
}
void Update()
{
if (_Test != Test)
{
_Test = Test;
Debug.Log("Changed");
TestArray = GameObject.FindGameObjectsWithTag("clone");
foreach (GameObject Clone in TestArray)
{
Destroy(Clone);
Debug.Log("Destroyed");
}
for (int i = 0; i < 4; i++)
{
Debug.Log(i);
Instantiate(TestObject, _TestObject);
TestObject.tag = "clone";
TestObject.name = "Clone" + i;
}
}
}
}
As you see I am instantiating an object and giving it a name for ease, but when I look in the hierachy it looks like this: Clone3, clone0, clone1, clone 2
And I want it to look like this: clone 0, clone1, clone2, clone3
I've tried setting the sibling index to the i variable but it gives the same result. Can someone explain to me why this is happening and tell me how I can fix it. (Also when I first start the game it doesn't instantiate anything only after I change the variable ones it does.)
Answer by Bunny83 · Jan 05, 2020 at 12:51 AM
This code:
Instantiate(TestObject, _TestObject);
TestObject.tag = "clone";
TestObject.name = "Clone" + i;
does not what you think it does. "TestObject" is your prefab. You actually clone your prefab and afterwards you modify your prefab. Note that you do not modify your already cloned object.
Just assume the for loop has already run once. That means the last thing you did to your prefab was naming it "clone3". Next time you run your loop it means your first object you instantiate will get the name clone3. Now you rename your prefab to "clone0". So the next loop iteration (i==1) you instantiate the prefab again but this time with the name "clone0". Again after you cloned it you change the prefab's name to "clone1". So you get the following names in order:
clone3
clone0
clone1
clone2
After the loop your prefab will be called again clone3.
The Instantiate method actually returns the cloned object which you completely ignore. You essentially have two options:
rename your prefab before you clone it
leave the prefab alone and rename the actual instance you just created.
I would highly recommend the second option. The first one, when tested in the editor, will actually modify your prefab asset permanently. So you should do:
TestObject.tag = "clone";
for (int i = 0; i < 4; i++)
{
GameObject clone = Instantiate(TestObject, _TestObject);
clone.name = "Clone" + i;
}
Note that I moved the tag setting out of the loop and actually modifed the prefab before we clone it. While this can be done I would highly recommend that you get rid of it completely and just set the tag on your prefab in the inspector.
Do you maybe know why the clones only appear when I change the variable myself and not when I start the game and the variable changes then?
Are you sure that your "Test" and "_Test" variables are different during the start? If they are the same of course you will not enter the if-statement. Since both of your varibles are public both are serialized in the inspector and will keep their value which you set in the inspector.
Though this double variable trick should only be a debugging tool. I would recommend to put the code inside your if statement into a seperate method which you can call when your variable changes. However this way you can also call it once from Start or use it in your actual production code at the proper times.
Answer by Horothenic · Jan 04, 2020 at 08:19 PM
I dont know why but maybe this thing gives you an incorrect order.
TestArray = GameObject.FindGameObjectsWithTag("clone");
Try this:
List<GameObject>testList = new List<GameObject>();
foreach(Transform t in myParentObject)
testList.Add(t.gameObject);
Just specify the parent object, that should give you the bjects in the correct order.
I tried it, but it still is giving me a wrong order. Can you maybe tell me why the very first time nothing happens and only after i change the test bool the clones spawn?
@jayvle, try this one. Make sure you put this after the for/foreach loop.
testList[0].transform.SetAsLastSibling();
Before I tried this code, I also had a similar problem while I was working on my level select screen where the last instantiated clone is the first sibling and not the last as we wanted to be. After I added this code after the for loop that instantiates my object on the scene, I was surprised it worked wonders that it now placed that last clone where it belongs.
Answer by nikunjsth5 · Mar 21 at 04:02 PM
@Bunny83 Your way worked. I have literally wasted my weekend over this issue, thanks man!
Your answer
Follow this Question
Related Questions
Multiple Cars not working 1 Answer
GetChild(0) returns nonexistent object 1 Answer
Instantiate script for randomly selecting sound is suddenly creating New Game Object in hierarcy?? 2 Answers
How to make a gameObject instantiate a prefab for every 250 damage taken ? 4 Answers
Want to spawn an object with button press, multiple times that gets higher each time? 1 Answer