• 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
Question by Cobo3 · Sep 25, 2014 at 06:22 PM · editorpropertydrawerondestroyonenable

OnEnable/Disable on property drawers

Hello everyone,

I have written a custom inspector for a custom class, and I make use of OnEnable, OnDisable and OnDestroy events to manage some things.

The thing is that now I would like it to not be a MonoBehaviour, in order to make it more versatile and usable. So i dropped the MonoBehaviour inheritance and wrote a custom property drawer for it. So far so good.

The problem comes when I try to do things on OnEnable/Disable/Destroy-like events; which are essential for it to work properly.

Say my custom class is called CC (for which a have a custom property drawer); and there's another Monobehaviour class named MC attached to a gameobject named GO. MC has a public variable of type CC.

Basically, I want to get notified in the property drawer whenever I select or diselect GO, and whenever MC gets destroyed.

I know there are no such events for a property drawer (tried it), so my question is: Is there anyway I could simulate those events from a property drawer? Any delegate or something?

Thanks in advance.

Comment
Ash-Blue

People who like this

1 Show 0
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

4 Replies

· Add your reply
  • Sort: 
avatar image

Answer by DESTRUKTORR · Jan 03, 2015 at 05:32 PM

The best method I could think of would be to use a custom MonoBehaviour (with the ExecuteInEditMode annotation) with the sole purpose of checking for and sending that event.

You'd need to somehow tell if and when the inspector was changed by something in the editor (either directly by the user or by some other script, or even the editor itself), and then you'd need to check to see if the script that the inspector was checking had any components in them that had property drawers associated with them.

There's likely a much better way to do this, assuming you reverse engineered the internal workings of the Unity Editor, but I wouldn't suggest that, for a pretty large number of reasons. Not least of which is that it would be horrifically unreadable and hackish.

I wouldn't worry about making an OnEnable method that works like the one in Editor scripts. Frankly, a single if statement checking to see if you've initialized something too expensive to do every frame would be a pretty inexpensive addition to the "OnGUI" or even the "GetPropertyHeight" methods. However, keep in mind that GetPropertyHeight (at least in my experience) is called at least 3 times per OnGUI call, and would be a lot less efficient to be doing checks in.

Comment
jpthek9
Ash-Blue

People who like this

0 Show 0 · 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

Answer by fwalkerCirca · Nov 20, 2018 at 06:34 PM

@Cobo3 Is has been a while. But I am dealing with this issue right now. Did you find an elegant solution for this?

Comment

People who like this

0 Show 0 · 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

Answer by NTG-Sera · Nov 07, 2019 at 02:37 PM

 [CustomPropertyDrawer( typeof( Example ) )]
 public class ExamplePropertyDrawer : PropertyDrawer
 {
     public ExamplePropertyDrawer() : base ()
     {
         Debug.Log( "ExamplePropertyDrawer Constructor" );
     }
     
     ~ExamplePropertyDrawer()
     {
         // Note: This is called by the GC; and not necessarily on inspector selection change.
         Debug.Log( "ExamplePropertyDrawer Destructor" );
     }
 }

This is what I've been using, seems to be working just fine.

However if you need a solution that fires for absolutely every property drawer individually:

 private bool initialized = false;
  
 public override void OnGUI( Rect position, SerializedProperty property, GUIContent label )
 {
     if ( !initialized )
     Init( property );
 }
 
 private void Init( SerializedProperty property )
 {
     initialized = true;
 }
Comment
Eldoir

People who like this

1 Show 0 · 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

Answer by IyroHaYuu · Aug 31, 2022 at 09:40 AM

Hello! I know this is an old topic, but I recently faced a similar problem. My goal was to cancel animation tasks for property display. So I created the following custom property drawer class to solve the problem. I hope this code will help someone. ; )

     public abstract class PropertyDrawerWithEvent : PropertyDrawer
     {
         bool init = true;
 
         ~PropertyDrawerWithEvent()
         {
             Destroy();
         }
 
         private void PlayModeStateChanged(PlayModeStateChange obj)
         {
             switch (obj)
             {
                 case PlayModeStateChange.ExitingEditMode:
                 case PlayModeStateChange.ExitingPlayMode:
                     Destroy();
                     break;
             }
         }
 
         private void SelectionChanged()
         {
             Disable();
         }
 
         /// <summary>
         /// Write code for when the property is first displayed or redisplayed.
         /// </summary>
         public abstract void OnEnable(Rect position, SerializedProperty property, GUIContent label);
 
         /// <summary>
         /// Write code for when the property may be hidden.
         /// </summary>
         public abstract void OnDisable();
 
         /// <summary>
         /// Write code for when the property is destroyed. (e.g. Releasing resources.)
         /// </summary>
         public abstract void OnDestroy();
 
         public abstract void OnGUIWithEvent(Rect position, SerializedProperty property, GUIContent label);
 
         public sealed override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
         {
             if (init) Enable(position, property, label);
 
             OnGUIWithEvent(position, property, label);
         }
         
         public void Enable(Rect position, SerializedProperty property, GUIContent label)
         {
             init = false;
             EditorApplication.playModeStateChanged += PlayModeStateChanged;
             Selection.selectionChanged += SelectionChanged;
             OnEnable(position, property, label);
         }
 
         public void Disable()
         {
             OnDisable();
             EditorApplication.playModeStateChanged -= PlayModeStateChanged;
             Selection.selectionChanged -= SelectionChanged;
             init = true;
         }
 
         public void Destroy()
         {
             OnDestroy();
             EditorApplication.playModeStateChanged -= PlayModeStateChanged;
             Selection.selectionChanged -= SelectionChanged;
             init = true;
         }
     }
Comment

People who like this

0 Show 0 · 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

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.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

6 People are following this question.

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

Related Questions

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

How to show type text in EditorGUI.ObjectField? 1 Answer

PropertyDrawer not updating in custom inspector. 0 Answers

Why PropertyDrawers shared same values? 2 Answers

Mixing custom editors with custom property drawers, possible ? 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