Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 13 Next capture
2021 2022 2023
1 capture
13 Jun 22 - 13 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
8
Question by Damyan · Dec 16, 2010 at 02:26 PM · editordestroydeleteondestroyondisable

Detect when GameObject has been deleted / removed from scene

Is there a way to determine when an object has been removed from the scene in the editor (eg the user has selected the object and pressed 'delete').

I would have expected OnDisable() to be called, but it doesn't seem to be.

Comment
Add comment
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

10 Replies

· Add your reply
  • Sort: 
avatar image
12

Answer by slkjdfv · Sep 02, 2013 at 12:31 PM

What I did to detect when an object is destroyed in edit mode is add a custom editor to it. So you create a blank script and attach a custom editor to it. In the custom editor use the OnDestroy method. Now this will get called even if you just deselect the object so in that method you need to check if the target script is null. If it's null you have deleted the object. So when you run the game since this is just for the unity editor you can tell it to remove this component at run time if you want. Here are the scripts :

 using UnityEngine;
 using System.Collections;
 
 public class ObjectChecker : MonoBehavior
 {
      //Nothing needed here
 }

 using UnityEngine;
 using UnityEditor;
 using System.Collections;
 
 [CustomEditor(typeof(ObjectChecker))]
 public class ObjectChecker : Editor
 {
     public void OnDestroy()
     {
         if ( Application.isEditor )
         {
             if(((ObjectChecker)target) == null)
                 //Do your code here
         }
     }
 }

Now this is a custom class for checking if the object is destroyed. You can put this OnDestroy code in any of your custom editor scripts if you want it to do something before the object is destroyed. This works for me with no issues. I use it in allot of my custom editors.

Comment
Add comment · Show 6 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image paraself · Sep 02, 2013 at 11:42 PM 1
Share

Thanks, This works well, but how to access the target's monobehaviour before it becomes null?

avatar image slkjdfv · Sep 03, 2013 at 05:44 AM 1
Share

Target is only null if you delete the GameObject or Remove the script component from the GameObject, other wise it's never null. For example, in the OnDestroy $$anonymous$$ethod target is already assigned cause it's a custom editor. you need to convert it to your class before it becomes usefull, but you can already access it. When you have a class inherit from Editor it acquires the variable "target". If you don't know how to make a custom editor check the UnityDocs for help on how to get started.

avatar image paraself · Sep 04, 2013 at 05:32 AM 1
Share
 public void OnDestroy()
     {
         if ( Application.isEditor )
         {
             if(((ObjectChecker)target) == null)
                 //Do your code here
         }
     }

Well. I mean, when I delete a gameObject, I want to access some of its member variables and functions before it's deleted. But in this code snippet. target is null. Any ideas how to do that?

avatar image Lev-Lukomskyi · Jun 15, 2014 at 06:09 PM 1
Share

To get deleted object in OnDestroy you can save it to static variable in OnDisable like this:

 [CustomEditor(typeof(HorizontalPortal))]
 public class HorizontalPortalEditor : Editor
 {
     static HorizontalPortal lastPortal;
 
     protected void OnEnable()
     {
         portal = (HorizontalPortal)target;
     }
 
     protected void OnDisable()
     {
         lastPortal = portal;
     }
 
     protected void OnDestroy()
     {
         if (target == null)
         {
             lastPortal.DoSomething();
             lastPortal = null;
         }
     }
 }
avatar image marsonmao · Jun 17, 2015 at 04:09 AM 0
Share

@Lev Lukomskyi I tested your method but lastProtal cant cache protal since target and portal are both null already when executing OnDisable(). What version were your method working? I'm using Unity 5.1 now and I think maybe the implementation has been changed...

Show more comments
avatar image
6

Answer by paraself · Sep 02, 2013 at 05:05 AM

Using ExecuteInEditMode and OnDestroy wont completely solve the issue. Because OnDestroy is also called when you hit play button in editor. For explicit detection of users deleting gameobject, my solution is:

For example, we have a xxx.cs monobehaviour attach to the gameobject that we wanna have deletion detection. Implement a corresponding editor script of xxx.cs like xxx_editor.cs (if you dont know how to do this, look at this tutorial link text)

in this xxx_editor.cs implement :

 void OnSceneGUI(){
     if (Event.current.commandName=="Delete") Debug.Log(target.name +" is deleted");
 }

now you can easily detect gameobject deletion right in side the editor script, however it might be triggered multiple times because OnSceneGUI is called multiple times a frame. but I am sure that's easy to solve.

PS: it only detect deletion in Scene view, if deletion happens in hierarchy, then it doesnt work. prbly need to use EditorApplication.hierarchyWindowChanged

Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image sotirosn · Nov 21, 2013 at 09:18 PM 1
Share

This is so painful if the user wants to delete from the inspector... I wish the custom Editor captured all events happening to objects it managed.

avatar image rklaus · Dec 12, 2016 at 09:52 PM 0
Share

Although this method does most of the work, there is a little problem lingering. When application is done playing, upon returning to unity the OnDestroy method is called when it does not actually indicate a removal from the hierarchy. I managed to overcome it using a little boolean cache. Check the answers for my answer and you'll see the code.

avatar image
4

Answer by Statement · Dec 16, 2010 at 03:07 PM

Your script must have ExecuteInEditMode attribute for that event to fire.

This will allow OnEnable, OnDisable etc be called when objects are created, when the game is run, stopped and object being deleted.

  • Note that adding this attribute might cause other problems since other methods might be called as well, depending on your script. Read the docs.
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Damyan · Dec 16, 2010 at 05:42 PM 0
Share

Thanks - it isn't clear to me how to tell that the object has been deleted in OnDisable(). This: http://answers.unity3d.com/questions/9123/ondestroy-notification suggests that there's not enough information available in OnDisable() to tell the different between disabling and deleting.

avatar image
1

Answer by luislodosm · Apr 24, 2017 at 07:52 AM

This works for detecting deleted objects in scene and hierarchy.

 [ExecuteInEditMode]
 public class MyClass : MonoBehaviour
 {
     void OnDestroy ()
     {
         if (Event.current != null && Event.current.commandName == "Delete")
             DoStuffBeforeDie ();
     }
 }
Comment
Add comment · Show 2 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ImperialDynamics · May 02, 2019 at 09:28 AM 0
Share

no, this never enters DoStuffBeforeDie

avatar image sl1nk3_ubi · Dec 16, 2020 at 01:40 AM 0
Share

This got me really close to a solution, on Unity 2019.4, commandName isn't "Delete" when the object is being deleted from the hierarchy but "SoftDelete" so I used this code to make it work:

 private void OnDestroy()
 {
     if (Event.current != null && Event.current.commandName.Contains("Delete"))
     {
         DoSomethingWhen$$anonymous$$anuallyDestroyed();
     }
 }

Also unfortunately, not event is triggered when deleted via the context menu in the hierarchy...

avatar image
0

Answer by rklaus · Dec 12, 2016 at 10:23 PM

Extending on @slkjdfv's answer, there is one slight problem with the solution. When application play is terminated, the OnDestroy method gets called too. To overcome this problem, I implemented and tested this solution:

 [CustomEditor(typeof(MyObject))]
 public class MyObjectEditor : Editor
 {
     private bool mRunningInEditor;

     private void OnEnable()
     {
         mRunningInEditor = Application.isEditor && !Application.isPlaying;
     }

     public override void OnInspectorGUI()
     {
         // do the magic here
     }

     public void OnDestroy()
     {
         if (mRunningInEditor && target == null)
             // Code here for the actual object removal
     }
 }
Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image ImperialDynamics · May 02, 2019 at 09:34 AM 0
Share

wow! THIS should be the accepted answer! It works! Thank you

Edit/Update: Actually no, sometimes it also runs when you enter Play mode. For the final solution check my answer

  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

10 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

OnDestroy() callback in Editor upon deleting selected GameObject - del key 5 Answers

Need help reassigning variables after the deletion of an object has been undone. 0 Answers

OnDestroy called when object lost focus in editor 2 Answers

using Contains(gameObject) to find and destroy a gameObject from a list 2 Answers

Deleting one object, not all objects at once. 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges