• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
24
Question by oliver-jones · Jan 08, 2014 at 03:41 PM · destroychildrenfind

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?

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image robertbu · Jan 08, 2014 at 03:46 PM 0
Share

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.

6 Replies

· Add your reply
  • Sort: 
avatar image
76
Best Answer

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();

Comment
Add comment · Show 9 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image robertbu · Jan 08, 2014 at 04:05 PM 0
Share

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.

avatar image yatagarasu · Jan 09, 2014 at 11:02 AM 0
Share

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.

avatar image MorphVGX · Dec 29, 2014 at 06:06 PM 3
Share

Is it correct to destroy objects in a collection you are cycling through? I guess it works because they are not destroyed immediately.

avatar image fadden · May 01, 2016 at 01:40 AM 0
Share

@$$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.

avatar image ErayT · Nov 24, 2017 at 11:35 AM 0
Share

Does not removing an element while removing break the iterator?

Show more comments
avatar image
24

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);
 }
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Thompsan · Oct 18, 2014 at 10:39 PM 13
Share

Small typo. The C# example should have i >= 0 just like the java example.

avatar image StormMuller · Feb 18, 2018 at 07:55 PM 0
Share

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.

avatar image
3

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 );
         }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image tonytopper · Jan 13 at 10:13 PM 0
Share

Why call DestroyImmediate and not just Destroy as Unity recommends?

avatar image
0

Answer by Xtro · Jan 08, 2014 at 03:48 PM

it looks like TextHolder has no children. Are you sure that TextHolder is referencing to the real text holder object in the scene? Make sure it's not referencing any prefab or something.

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image oliver-jones · Jan 08, 2014 at 04:04 PM 0
Share

I am 100% sure that TextHolder is the correct reference - I even called Destroy on it, and it was successfully Destroyed.

avatar image
0

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);
             }
         }

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

31 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Make into child of a parent in c# 1 Answer

Destroying children (sounds horrible) 4 Answers

transform.Find always returns null 1 Answer

using Contains(gameObject) to find and destroy a gameObject from a list 2 Answers

Simple In game search field 2 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges