- Home /
Destroy All Children of Object
Hello,
I can't get my head around this, I have a game empty called TextHolder. At times, this TextHolder is populated with text objects (via Instantiate), as children. I want to be able to get all the children (text objects) of the TextHolder and Destroy them when needed.
I don't want to cache them, as in adding them to an array whilst I Instantiate them, I want to be able to search the 'TextHolder' object for any children, and Destroy them:
var allChildren = TextHolder.GetComponentsInChildren(Transform);
for (var ac = 0; ac < allChildren.length; ac ++){ //var child : Transform in allChildren
print("Removing old text modules");
Destroy(allChildren[ac].gameObject);
}
Although this doesn't actually do anything, its as if the TextHolder has no children.
What am I doing wrong here?
I see one issue here, but it is doubtful that it is the root of your bug. GetComponentsInChildren() gets the root as well as the children. So if you don't want to delete 'TextHolder', you have to add a condition to your loop.
Answer by yatagarasu · Jan 08, 2014 at 03:46 PM
Hmm. Your code is too complex. I even don't know what it is intended to do. But maybt you should try transform
instead of Transform
Here is more compact working code.
foreach (Transform child in TextHolder.transform) {
GameObject.Destroy(child.gameObject);
}
If TextHolder is an instance of an object, not class. If you want to simply remove all children of current object you can write
foreach (Transform child in transform) {
GameObject.Destroy(child.gameObject);
}
or you can write extension method for Transform class and call it on objects transform you want to clear
public static class TransformEx {
public static Transform Clear(this Transform transform)
{
foreach (Transform child in transform) {
GameObject.Destroy(child.gameObject);
}
return transform;
}
}
in your code myObject.transform.Clear();
Javascript syntax for foreach:
for (var child : Transform in TextHolder.transform)
But the main difference between his solution and yours is the use of GetComponentsInChildren(). His code only finds the first level children, but Destory() should take care of the grandchildren. In fact that might be the root of your issues.
oliver, sorry didn't know you are writing on js. you code would look much the same on c#. with only two exceptions, no print in c# and necessity to write typeof(Transform) in GetComponentsInChildren call.
nevertheless iteration through transform (which in this case behaves as a list of its children) is right way to iterate objects children. GetComponentsInChildren seems like an overkill. So I think robrtbu's code should work.
Is it correct to destroy objects in a collection you are cycling through? I guess it works because they are not destroyed immediately.
@$$anonymous$$orphVGX: it works because Destroy is deferred -- the collection isn't modified until the end of the frame. DestroyImmediate would be bad.
See also this thread, where it's also recommended to call transform.DetachChildren()
after the foreach.
You should mark your answer as deprecated. @frogsbo 's answer is the only correct one
Answer by frogsbo · May 29, 2014 at 08:23 PM
in JS:
var childs : int = transform.childCount;
for (var i = childs - 1; i >= 0; i--)
{
Destroy(transform.GetChild(i).gameObject);
}
in C:
int childs = transform.childCount;
for (int i = childs - 1; i > 0; i--)
{
GameObject.Destroy(transform.GetChild(i).gameObject);
}
Small typo. The C# example should have i >= 0 just like the java example.
I found this answer to be more correct. Because as @$$anonymous$$orphVGX mentioned in the top answer. Deleting an object from the collection you are enumerating is not smart. In my editor script I had to use DestoryImmediate
. Using the foreach method, I noticed that not all objects were destroyed at once. I would have to recursively call the foreach loop to destroy all the children. For loop worked perfectly first time around. Other than the typo @Thompsan mentioned.
Answer by normand · Aug 26, 2018 at 08:18 AM
So you create a tag just to delete your Objects like I did. But, like @frogsbo said it: work perfectly. Just don't forget to add = at i>0 just like @Thompsan mentioned.
int childs = clone.transform.childCount;
for (int i = childs - 1; i >= 0; i--) {
GameObject.DestroyImmediate( clone.transform.GetChild( i ).gameObject );
}
Why call DestroyImmediate and not just Destroy as Unity recommends?
Answer by rich2020 · Sep 23, 2016 at 12:15 PM
Because my objects are loaded via a Coroutine, the above examples as well as the typical approach of getting all GameObjects with a tag (using 'FindGameObjectsWithTag'), iterating over them and removing them, I used the following approach:
public IEnumerator DoDeleteAll()
{
while (Holder.transform.childCount > 0)
{
var items = GameObject.FindGameObjectsWithTag("YOUR_TAG");
foreach (var item in items)
{
Destroy(item );
}
yield return new WaitForSeconds(0.001f);
}
}
Answer by FabDynamic · Oct 28, 2018 at 05:07 AM
For posterity I wanted to add here what worked for me:
var children = new List<GameObject>();
foreach (Transform child in transform) children.Add(child.gameObject);
children.ForEach(child => Destroy(child));
I got that code from this forum post: https://forum.unity.com/threads/deleting-all-chidlren-of-an-object.92827/
Your answer
Follow this Question
Related Questions
(C#) How do I run something in my child's script? 2 Answers
using Contains(gameObject) to find and destroy a gameObject from a list 2 Answers
Find and destroy object 2 Answers
Destroying and instantiating parent GameObject 0 Answers
Destroy(other.gameObject) isn't destroying parent, only children 2 Answers