Editor and DestroyImmediate

Why do I have to do this? Is there a better way? When working in the procedural generation space, it’s would seem to be a given that code would be running in the editor and in runtime.

I would expect Unity to abstract the need to do this away from me.

        public static void AdaptiveDestroy(GameObject gameObject)
        {
#if UNITY_EDITOR
            UnityEngine.Object.DestroyImmediate(gameObject);
#else
            UnityEngine.Object.Destroy(gameObject);
#endif
        }

8013431--1031393--upload_2022-4-1_12-20-21.png

Destroy doesn’t happen until end of frame in a running game, so it is a preferred way of going.

You actually CAN use DestroyImmediate() in your runtime game, assuming you’re careful.

You cannot use Destroy() in the editor because well, there is no notion of frame-frame-frame from the actual game engine side of things. Things aren’t really running, the frame never ends, so Destroy() doesn’t.

Anyway, that’s my understanding of things… as always I’m open to anyone correcting the above.

No, your implementation is just not right. The issue is about playmode or edit time and not platform dependent. If you use your “AdaptiveDestroy” you would always use DestroyImmediate, even when testing in the editor which is wrong and could lead to other bugs in a build which you could not detect during testing this way.

If you call Destroy during edit time it seems that you’re mixing editor code with runtime code at some place. Editor code has to use DestroyImmediate while runtime code should use Destroy unless there’s a good reason for DestroyImmediate.

I use this for such occasions:

public static void SmartDestroy(UnityEngine.Object obj)
{
   if (obj == null)
   {
       return;
   }

#if UNITY_EDITOR
   if (!Application.isPlaying)
   {
       GameObject.DestroyImmediate(obj);
   }
   else
#endif
   {
       GameObject.Destroy(obj);
   }
}
3 Likes

Regarding, mixing editor and runtime code, to an extent, that’s my point I think. Writing two sets of code seems odd and inefficient to me for certain cases. And really, I suspect, only makes sense to people who’ve gotten used to it by being inside the Unity world long enough, in my opinion anyway. As well, this is the D in CRUD so it’s something that’s going to happen a lot in both the editor and in a game.

I think I have to assume by you saying, "even when testing in the editor " you mean Play Mode? In which case I was wondering if I needed to add a logic check for that inside the first block, a la, EditorApplication.isPlaying which was a suspicion. So thanks.

Thinking …

#if UNITY_EDITOR
            if (EditorApplication.isPlaying)
            {
                Destroy(gameObject);
            }
            else
            {
                DestroyImmediate(gameObject);
            }
#else
            Destroy(gameObject);
#endif

My larger thought was less about why this is the case in Unity (that’s good to get clear though). It’s more so that we shouldn’t have to even think about this in the first place.

Ah yes, more refined. I like it.

Yes, that’s probably the best solution in case you have some shared edit and runtime code.

1 Like