- Home /
OnDestroy() callback in Editor upon deleting selected GameObject - del key
Hi there. I have a fallowing problem, I need to do some logic when a user deletes a GameObject in the scene. Ideally it should work at any time when the GameObject gets deleted in the editor, however I really need a callback upon pressing delete key. I have tried adding OnDelete() function to a script attached to this GameObject: that failed. I have also tried to execute the script in edit mode - that also failed. I guess I could add some messy logic to the update function and execute that in the editor, it unfortunately does not sound very clean. I am kind of stuck, please help.
Answer by kamil.slawicki · Jan 15, 2013 at 12:02 PM
Ok, take it back. It turns out that I cannot spell destroy properly. Adding [ExecuteInEditMode]
ensures that OnDestroy is being triggered properly in the editor.
Though it triggers OnDestroy() properly in Editor, yet it also triggers OnDestroy() when switching from editor to runtime after hitting Play button. Can anyone suggest a better solution which only detect gameobject deletion. $$anonymous$$y code sample:
void OnDestroy(){
if ((Application.isPlaying==false)&&(Application.isEditor==true)&&(Application.isLoadingLevel==false))
Debug.Log(this.name + " is destroyed");
}
Application.isLoadingLevel is now deprecated.
As a potential workaround, when OnDestroy is called while loading a level in the editor, Time.frameCount and Time.renderedFrameCount appear to always equal zero (0). The two Time properties appear to be greater than zero when manually deleting gameObjects in the editor.
This no longer appears to work with ScriptableObject(s) as of 5.6.2f1. OnDestroy never triggers, but events like Awake seem to trigger correctly. $$anonymous$$ight be a bug.
Answer by Iq110 · Jun 30, 2020 at 10:35 AM
I found that this method works on new Unity versions (2019.4):
private void OnDestroy()
{
#if UNITY_EDITOR
if (!UnityEditor.EditorApplication.isPlayingOrWillChangePlaymode)
{
if (Time.frameCount != 0 && Time.renderedFrameCount != 0)//not loading scene
{
if (componentToDestroy != null)
DestroyImmediate(componentToDestroy);
}
}
else
#endif
{
if (componentToDestroy != null)
Destroy(componentToDestroy);
}
}
Answer by sindrijo_ · Nov 28, 2016 at 11:11 AM
I little gotcha for Editor side: OnDestroy will only be called on an object that have had "OnAwake" called on them, meaning if you somehow spawn an object as a child on a disabled object that has your script or you add your script to a disabled object OnDestroy will not be called if you never activate the object.
Answer by IgorAherne · Jan 25, 2017 at 06:46 PM
The following code can be placed directly into MonoBehavior will allow you to get a callback, even though object was "technically deleted". But, you are not allowed to use anything like this.gameObject
or this.transform
etc.
However, you could use this to "clean-up" any entries from your singletons, static classes or Scriptable objects who were pointing at this
, etc (their references to it would now exist as 'null', meaning their Lists or Dictionaries might contain null entries).
#if UNITY_EDITOR
//tells if we have already hooked-up to the SceneView delegate, once, some time ago
[System.NonSerialized]
bool linked_SV = false;
public void OnDrawGizmos() {
if(linked_SV == false) {
linked_SV = true;
SceneView.onSceneGUIDelegate -= OnSceneDraw;
SceneView.onSceneGUIDelegate += OnSceneDraw;
}
}
void OnSceneDraw(SceneView sceneView) {
try {
this.gameObject.name = this.gameObject.name;
}
catch{
SceneView.onSceneGUIDelegate -= OnSceneDraw;
// this gameObject was destroyed.
OnDestroy();
SomeOtherFunction();
return;
}
#endif
For example, I was using Graphics.DrawMesh, from within my OnSceneDraw(), and was successfully able to "unhook" my function from the SceneView.OnSceneViewDelegate
, even after unity said it was deleted.
This was possible since unity "fakes the object's deletion", by substituting its own, special, "NULL-value". That's why after destroying any gameObject, it's also best to set the references to null
, manually. Garbage collector will then remove it.
Your answer
Follow this Question
Related Questions
When I Multi-select gameobjects and press 'delete' 'OnDestroy' func is not called? 0 Answers
Need help reassigning variables after the deletion of an object has been undone. 0 Answers
I cant delete multiple instantiated prefabs 0 Answers
Detect when GameObject has been deleted / removed from scene 10 Answers