Brief intro, here’s the hierarchy i’m working with. Note the many duplicate “Manipulator…” objects several layers deep.
I’m attempting to programmatically delete them all and then replace them with a single clean one
(yes i know this is easy to do manually. I’m writing a tool for automating things)
The section of relevant code for this is
void SetupManipulators()
{
for(int i = 0; i < ManipulatorParentNames.Length; i++)
{
string s = ManipulatorParentNames[i];
Transform t = ObjectTools.FindChildByName(s, transform);
foreach (Transform v in t)
{
Debug.Log("Checking: " + v.gameObject.name);
if (v.gameObject.name.ToLower().Contains("manipulator"))
{
Debug.Log("Destroying: " + v.gameObject.name);
DestroyImmediate(v.gameObject);
}
}
GameObject g = Instantiate(manipulator);
g.transform.parent = t;
g.transform.localPosition = ManipulatorLocalPositions[i];
}
}
There are some references to arrays and functions there. ManipulatorParentNames currently only contains one word, “Jaw”
Here’s the debug output from running that code, on that hierarchy (setup complete is in the function that called this one)
And how the hierarchy looks afterwards
What the devil is going on here?
As can be clearly seen, it checks the first and second child, but then skips every alternating one starting from the third.
I’m guessing the “stack is falling”… i.e.
get 1 delete 1 => 2 becomes 1 mwhahahah I’m not going to get deleted, 3 become 2, 4 become 3 etc.
get 2 delete 2 => 1 is still 1, 3 becomes 2 mwhahahah I’m not going to get deleted, 4 becomes 3 etc.
so a while loop removing the first one until the length is empty would work
When you call DestroyImmediately from inside your foreach loop, I suspect it’s messing with the loop iterators because you’re immediately removing the child from the hiearchy. To do a safe delete, you’d want to do something like:
List<Transform> toBeDeleted = new List<Transform>();
foreach (Transform v in t)
{
Debug.Log("Checking: " + v.gameObject.name);
if (v.gameObject.name.ToLower().Contains("manipulator"))
{
toBeDeleted.Add(v);
}
}
for (int i = 0; i < toBeDeleted.Count; i++)
{
var v = toBeDeleted[i];
Debug.Log("Destroying: " + v.gameObject.name);
DestroyImmediate(v.gameObject);
}
toBeDeleted.Clear();