- Home /
Even though I destroy all my child GameObject the transform.childCount still returns the undestroyed childcount?
I am making a quiz Game and in my game I have an Option Holder which holds all the options which are Unity UI prefabs. And I have a function called FlushOutAllOptions() which will destroy all the Children of the OptionsHolder GameObject. But even though I destroy all the Children of this gameObject the childCount of the OptionsHolder still returns the value as if they were not destroyed.
public void FlushOutAllOptions()
{
var children = new List<GameObject>();
foreach (Transform child in transform)
children.Add(child.gameObject);
children.ForEach(child => Destroy(child));
Debug.Log("Flushed Out all the questions");
Debug.Log("Child Count after Flushing : " + transform.childCount);
//This Below Method also doesnt work
//for (int i = 0; i < transform.childCount; i++)
//{
// Destroy(transform.GetChild(i).gameObject);
//}
//Debug.Log("Flushed Out all the questions");
//Debug.Log("Child Count after Flushing : " + transform.childCount);
}
I do know that Destroy takes time and it gets called only after the current frame. But even during the next frame the childCount is returning the same value only after the 2nd frame from where the destroy is called the childcount changes. So Its making my scripting very difficult. Please tell me how to handle this because none of the functions are called in the Update or FixedUpdate or LateUpdate. The removal of the Options i.e. the Calling of the FlushOutAllOptions() and the Setting the Next set of Options occur at the Click of the Submit button for the current Question. and that is the reason why the childCount is not changing, so How do I handle this scenario?
So it would be better if anyone can demonstrate a sample scene where in the click of a button you destroy all the child gameObjects and then add a bunch of child GameObjects only if the childCount has returned 0 and all this in the click of a button and not in an Update or FixedUpdate or LateUpdate.
Answer by Dave-Carlile · Jul 06, 2016 at 08:13 PM
When you destroy a game object it isn't actually destroyed until the end of the frame.
From the Destroy documentation:
Actual object destruction is always delayed until after the current Update loop, but will always be done before rendering
If you log the count after rendering or during the next frame you should see it go to 0.
If you rely on the children being destroyed immediately because you're adding other children back, you can use DestroyImmediate, although read the documentation carefully since it has some potential issues.
If you don't want to risk DestroyImmediate you could try using DetachChildren after you destroy them - or you could re-parent them yourself as you're looping through your list. I guess it's possible they don't get re-parented until the end of the frame but I don't believe that's the case.
@Dave Carlile Ya I know but that is where my problem Lies. Please see my Updated Question to better Understand my problem.
@Dave Carlile Ok thanks for the Help the DetachChildren seems to kinda work since it is executed immediately I get the childCount as 0 which is what I want but the child Objects dont get destroyed and all those Options UI just becomes unparented. And DetachChildren does not seem to return anything. So how do I destroy those Unparented Child GameObjects?
@Vickylance You would still need to destroy them first before detaching. They'll get destroyed at the end of the frame, but since you detach your child count will be 0.
So the process would be this:
Loop through like you are now, calling destroy on each child
Optionally set the parent to null on each at this time
Or once the loop is complete call DetachChildren to remove them all
Your child count after the loop will be 0. The children still exist at this point but they are root game objects. They will be removed at the end of the frame.
If it were me I'd probably just go with DestroyImmediate.
@Dave Carlile I want to find a way to FlushOutOldOptions() and then AddInNewOptions() to be only called if the childCount is 0 and I want this to happen in the Click of the Submit button.
Thank you! I had been staring at my code for 2 hours and could not find any problems. I used DetachChildren after I destroyed my gameobject and it worked perfectly! Thanks again!
Answer by ricarious · Jun 13, 2019 at 08:42 PM
Note if you SetParent(null)
for each deleted child during the loop, the loop will be screwed (i.e. you cannot modify the loop parameters while executing the loop, SetParent(null)
will change the array that you are looping on).
DetachChildren()
after the loop completes is the way to go imo.