Destroy Child Object(s) OnValidate?

Is there any way to destroy child objects during OnValidate and/or in edit mode?

using UnityEngine;

public class DestroyChildrenTest : MonoBehaviour
{
    private void OnValidate()
    {
        foreach (Transform child in transform)
        {
            DestroyImmediate(child);
        }
    }
}

The code above doesn’t work and throws the following error message:

Destroying components immediately is not permitted during physics trigger/contact, animation event callbacks or OnValidate. You must use Destroy instead.

But using Destroy() instead also doesn’t work and throws this error message:

Destroy may not be called from edit mode! Use DestroyImmediate instead.

I’ve tried using co-routines and WaitForEndOfFrame() or WaitForFixedUpdate(), but that didn’t seem to do anything.

In the editor the method you suggested should work.

Use a coroutine to wait until the end of the frame and then destroy the gameobject.

    public bool toggleValidation;

	void OnValidate () {

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

    IEnumerator Destroy(GameObject go)
    {
        yield return new WaitForEndOfFrame();
        DestroyImmediate(go);
    }

First of: typo in class name.

And for the answer:

If OnValidate() doesn’t work, why not get rid of it?

The solution consists of adding a custom button in the inspector and discarding the OnValidate() function. It is clearer and better, yet can be confusing if you never tried creating your own inspector.

Basically, what you will do is add a new script, which will hold the functions of the custom inspector, in this case a button and paste in the two scripts I provided in the end. I don’t know whenever you know the topic, so I won’t explain every aspect of the code, it is pretty basic. Fix the typo.

Script for replacement with current one:

using UnityEngine;
 
public class DestoryChildrenTest : MonoBehaviour
{
    public void DestroyChildren()
    {
        foreach (Transform child in transform)
        {
            DestroyImmediate(child.gameObject);
        }
    }
 }

New script (name doesn’t matter)

using UnityEngine;
using System.Collections;
using UnityEditor;

[CustomEditor(typeof(DestoryChildrenTest))]
public class ObjectBuilderEditor : Editor
{
    public override void OnInspectorGUI()
    {
        DrawDefaultInspector();

        DestoryChildrenTest myScript = (DestoryChildrenTest)target;

        if (GUILayout.Button("DestroyChildren"))
        {
            myScript.DestroyChildren();
        }
    }
}

You could create a class in your editor folder marked InitializeOnLoad with a set of GameObjects to delete:

[InitializeOnLoad]
public class Example { 
    public static HashSet<GameObject> DestroyOnUpdate = new HashSet<GameObject>();
    // ... the following code...
 }

In it’s static constructor, register a callback for EditorApplication.update:

static HierarchyDecorator()
{
    EditorApplication.update += Update;
}

In the Update method, delete any GameObjects if you are in edit mode:

public static void Update()
{
    if (EditorApplication.isPlaying)
        return;
    foreach (var go in DestroyOnUpdate) {
        Destroy(go);
    }
    DestroyOnUpdate.Clear();
}

In a components validate method, add the gameObject you want to destroy to the list:

private void OnValidate(){
    Example.DestroyOnUpdate.Add(gameObject);
}

This is a bit heavy handed, but should work.

This question is a couple of years old, but I just encountered this same problem. The answer by @MikeNewall is partially the solution, but you can’t run coroutines in the editor mode although it may be coming to Unity eventually according to this.

I found a workaround using this little library: Unity Editor Coroutines.

This makes deleting the GameObjects really simple.

         public bool toggleValidation;
     
         void OnValidate () {
     
             foreach (Transform child in transform)
             {
                // The really important part, using the library
                EditorCoroutines.EditorCoroutines.StartCoroutine(Destroy(child.gameObject), this);
             }
         }
     
         IEnumerator Destroy(GameObject go)
         {
             yield return new WaitForEndOfFrame();
             DestroyImmediate(go);
         }

i’m having the same issue with this line
** var go = Instantiate(FloatingTextprefab,this.transform.position,this.transform.rotation);
go.GetComponent().text = finaldamage.ToString();**

I don’t know why

Something like this?

void OnValidate() => UnityEditor.EditorApplication.delayCall += SafeValidate;

void OnValidateSafe()
{         
     foreach (Transform child in transform)
         DestroyImmediate(child);
}

*from https://forum.unity.com/threads/onvalidate-and-destroying-objects.258782/#post-1710165 *