How to destroy and remove all children from an object? Not possible?

I have a empty object called ‘map’ it has a script on it called ‘map’. Its main function is to create a small map of tiles and remove them. Once they are created they are moved onto the ‘map’ empty as children.

Next time a change occurs and I want to rebuild the map I try to destroy the current ones, this results in them all moving into the main part of the scene.

Here is the relevant code

  if (transform.childCount > 0)
        {
            Debug.Log("Cleaning map...");
            while (transform.childCount > 0)
            {
                Transform child = transform.GetChild(0);
                child.parent = null;
                Destroy(child.gameObject);
            }
        }

        Debug.Log("Generating map...");
        if (HexGrid == null)
            HexGrid = new Grid2D<Hex>(width, height);
        HexGrid.Clear();

        for (int x = 0; x < width; x++)
        {
            for (int y = 0; y < height; y++)
            {
                float xPos = x * XOffset;
                 
                // Are we on an odd row?
                if (y % 2 == 1)
                    xPos += XOffset / 2f;

                GameObject node = Instantiate(hexPrefab, new Vector3(xPos, 0, y * ZOffset), Quaternion.identity);
                HexGrid.Set(x, y, node.GetComponent(typeof(Hex)) as Hex);
                
                node.name = "Hex_" + x + "_" + y;
                
                node.GetComponent<Hex>().GridLocation.X = x;
                node.GetComponent<Hex>().GridLocation.Y = y;
                
                node.transform.SetParent(transform, true);
                node.isStatic = true;
            }
        }

You can use an foreach to get each child in the parent (map) and use the Destroy(); function.

foreach (Transform child in transform)
        {
            Destroy(child.gameObject);
        }

If you wish, you can also nullify the parent.

foreach (Transform child in transform)
        {
            child.parent = null;
        }

Ok, since we now have a bit more information lets write an answer ^^.

Destroy only works at runtime. It actually delays the destruction to the end of the current frame. At edittime this won’t happen at all. Also when instantiating prefabs in the editor you may use the proper editor classes / methods instead. The method Instantiate is ment for runtime instantiation and will break the prefab connection. At edit time you usually use PrefabUtility.InstantiatePrefab which will preserve the prefab connection.

As Bonfire already said to destroy anything at edit time you have to use DestroyImmediate. Running runtime classes at edit time (probably with ExecuteInEditMode) is inherently dangerous. Most changes done at edit time are permanent. It’s easy to mess things up. I’m not sure what you actually want to implement here, but if that functionality is only used at edit time you should consider writing an editor class instead. Either a custom inspector for a runtime class (like Unity’s Terrain editor for example) or a seperate EditorWindow (like the AnimationWindow, MecanimWindow, …)

Editor classes are seperated from runtime code and they can additionally use the whole UnityEditor namespace which contains many classes and methods to actually edit assets and handle general editor features like the Undo class.

Since clearing out child objects from a parent seems like a repetitive process, I suggest just adding an extension method to GameObject, that way you can re-use wherever needed, e.g. go.Clear();

Example below:

static public class GameObjectExtensions
{    
    static public void Clear(this GameObject go)
    {
        for (int i = go.transform.childCount - 1; i >= 0; i--)
        {
            GameObject.Destroy(go.transform.GetChild(i).gameObject);
        }
    }   
}

So, for example in the OP, you could just write something like this.

transform.gameObject.Clear();

Simplified answer:

for (var i = transform.childCount; i-- > 0;) {
      Destroy(transform.GetChild(0).gameObject);
}

OR:

while(transform.childCount > 0){ 
    Destroy(transform.GetChild(0).gameObject);  
}

The only guaranteed way to accomplish this, since calling Destroy marks an object for destruction which occurs the following frame (allowing methods like OnDestroy to actually work) is this

for(int i=transform.childCount-1;i>=0;i--) {
    if(Application.isPlaying) {
        Destroy(transform.GetChild(i).gameObject);
    } else {
        DestroyImmediate(transform.GetChild(i).gameObject);
    }
}

or as an extension method (the way I prefer to do this)

public static void Clear(this Transform transform) {
    if(!transform) {
        return;
    }

    for(int i = transform.childCount - 1; i >= 0; i--) {
        if(Application.isPlaying) {
            Object.Destroy(transform.GetChild(i).gameObject);
        } else {
            Object.DestroyImmediate(transform.GetChild(i).gameObject);
        }
    }
}