Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Destroy all Children!

Discussion in 'Scripting' started by andrescuevas, Jun 2, 2019.

  1. andrescuevas

    andrescuevas

    Joined:
    Apr 23, 2019
    Posts:
    24
    Haha the title.

    I want to destroy all children of a game object with the following while. I think every loop should destroy one Child until there are none left and the condition is met but it loops infinitely and crashes.

    Code (CSharp):
    1.  while( eP.transform.childCount != 0)
    2.         {
    3.             Destroy(eP.transform.GetChild(0));
    4.         }
    Can somebody tell me why please?
     
    mmmshuddup likes this.
  2. Lurking-Ninja

    Lurking-Ninja

    Joined:
    Jan 20, 2015
    Posts:
    9,913
    Read the manual:
    https://docs.unity3d.com/ScriptReference/Object.Destroy.html

    So just go through the list of children and destroy them. Better if you put them in a parent game object and just destroy that one (in case you need eP in the future).
     
    halley likes this.
  3. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    You're trying to destory the trasnform, you need to destroy the game object.
    Code (CSharp):
    1.   Destroy(eP.transform.GetChild(0).gameObject);
     
  4. TheRealRan

    TheRealRan

    Joined:
    Jun 3, 2019
    Posts:
    18
    You could also do the following foreach:

    Code (CSharp):
    1. foreach(Transform child in eP.transform)
    2. {
    3.     Destroy(child.gameObject);
    4. }
    If you want to keep it the same way as you have, the answer from the person above is most likely what you are looking for.
     
  5. YetAnotherKen

    YetAnotherKen

    Joined:
    Jun 17, 2019
    Posts:
    30
    If you destroy a GameObject will it's components be automatically garbage collected by the Unity Engine?
     
  6. Vryken

    Vryken

    Joined:
    Jan 23, 2018
    Posts:
    2,106
    Yes.
     
    YetAnotherKen likes this.
  7. reckless_glitch

    reckless_glitch

    Joined:
    Nov 22, 2013
    Posts:
    14
    That looks so clean and easy, and as many clean and easy solutions:
    it doesnt work!
    Result: it kills only half the children.

    I think it translates into something like (EXAMPLE)

    child[0] Anna
    child[1] Bob
    child[2] Caspar

    kill them all -> kill child[0] then kill child[1] then kill child[2]

    1) kill child[0] -> Anna dies (now Bob is child[0] and Caspar is child[1] )
    2) kill child[1] -> Caspar dies (now only bob is left as Child[0] )
    3) kill child[2] -> no child[2]
    Hey, who are you?
    I am Bob.
    Are you child[2]
    no i am child [0]
    okay go!

    I dont trust while but:


    while ( transform.childCount>0) Destroy(transform.GetChild(0).gameObject);
     
    Last edited: Jun 16, 2022
  8. John_Leorid

    John_Leorid

    Joined:
    Nov 5, 2012
    Posts:
    626
    And that's why you always move backwars in a for loop when you execute code that can alter the collection. Actually it's fascinating that you don't got a CollectionModified exception.

    Code:


    Code (CSharp):
    1. for(int i = eP.transform.childCount - 1; i >= 0; i--)
    2. {
    3.     Destroy(eP.transform.GetChild(i).gameObject);
    4. }
     
    Bunny83 likes this.
  9. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,895
    I mean using Destroy means they don't actually get destroyed until the end of the frame. It's more akin to flagging something for destruction.

    I've used the code that 'doesn't work' plenty of times with zero issues.
     
    SparrowGS and mopthrow like this.
  10. SparrowGS

    SparrowGS

    Joined:
    Apr 6, 2017
    Posts:
    2,536
    How are you using the code, where is this loop called from?
    Like @spiney199 said, this code should work just fine.
     
  11. sip-sip

    sip-sip

    Joined:
    Jan 20, 2020
    Posts:
    1
    you need to use a coroutine ı preffer IEnumerator and make the frames wait for one tick which you can do it by
    Code (CSharp):
    1. private IEnumerator destoryAllChildren(){
    2.     while ( transform.childCount>0) {
    3.         Destroy(transform.GetChild(0).gameObject);
    4.         yield return null;
    5.     }
    6. }
    writing using System.Collections; at the begginning of the whole code is a need
    and to call the function we use StartCoroutine e.g.;
    Code (CSharp):
    1. StartCoroutine(destoryAllChildren(///overload\\\));
     
    Last edited: Jun 28, 2022
  12. nikk98

    nikk98

    Joined:
    Mar 8, 2021
    Posts:
    43
    You don't need to use a coroutine. The following code adds two extensions that can delete children of a gameobject, in one frame. You need to use the second one in editor scripts.
    After you add the code, you can use it as follows:

    Code (CSharp):
    1. var gameObject = Find("SomeGameObject");
    2. gameObject.DestroyChildren();

    Code (CSharp):
    1.  
    2. public static class GameObjectExtensions {
    3.   public static void DestroyChildren(this GameObject t) {
    4.       t.transform.Cast<Transform>().ToList().ForEach(c => Object.Destroy(c.gameObject));
    5.   }
    6.  
    7.   public static void DestroyChildrenImmediate(this GameObject t) {
    8.       t.transform.Cast<Transform>().ToList().ForEach(c => Object.DestroyImmediate(c.gameObject));
    9.   }
    10. }
    11.  
     
  13. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    5,895
    That is an absurdly unnecessary amount of Linq that could be done with just:
    Code (CSharp):
    1. public static void DestroyAllChildren(this GameObject go)
    2. {
    3.     foreach (Transform transform in go)
    4.     {
    5.         UnityEngine.Object.Destroy(transform.gameObject);
    6.     }
    7. }
     
    Last edited: Sep 4, 2022
    SparrowGS likes this.