Search Unity

  1. Get all the Unite Berlin 2018 news on the blog.
    Dismiss Notice
  2. Unity 2018.2 has arrived! Read about it here.
    Dismiss Notice
  3. We're looking for your feedback on the platforms you use and how you use them. Let us know!
    Dismiss Notice
  4. The Unity Pro & Visual Studio Professional Bundle gives you the tools you need to develop faster & collaborate more efficiently. Learn more.
    Dismiss Notice
  5. Improve your Unity skills with a certified instructor in a private, interactive classroom. Learn more.
    Dismiss Notice
  6. ARCore is out of developer preview! Read about it here.
    Dismiss Notice
  7. Magic Leap’s Lumin SDK Technical Preview for Unity lets you get started creating content for Magic Leap One™. Find more information on our blog!
    Dismiss Notice
  8. Want to see the most recent patch releases? Take a peek at the patch release page.
    Dismiss Notice

Create a PropertyDrawer context menu

Discussion in 'Extensions & OnGUI' started by Estecka, Aug 2, 2018.

  1. Estecka

    Estecka

    Joined:
    Oct 11, 2013
    Posts:
    51
    Is it possible to create a right-click menu on a specifc propertyDrawer? Just like when you right click on an element in a list or an array.
    (I noticed that when using my custom propertyDrawer, the array's context menu no longer work, so I assume this menu is actually a part of the propertyDrawer ?)

    I found a lot of doc on how adding entries to various existing menu, but nothing about specifc properties.
     
  2. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    279
    Sure. Check for a MouseDown event with a button of 1, make sure the mouse position is inside the property rect, then create a
    GenericMenu
    and call
    ShowAsContext
    on it.
     
    Estecka likes this.
  3. Estecka

    Estecka

    Joined:
    Oct 11, 2013
    Posts:
    51
    @Madgvox Thanks a lot for the directions !
    If it can help anyone else, this is what the code would look like :

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using UnityEditor;
    5.  
    6. public class CustomDrawer : PropertyDrawer {
    7.     // Methods that will be called by the Context menu
    8.     SerializedProperty activeProperty;
    9.     void Expand     () { activeProperty.isExpanded = true;  }
    10.     void Unexpand() { activeProperty.isExpanded = false; }
    11.  
    12.  
    13.     public override void OnGUI (Rect position, SerializedProperty property, GUIContent label) {
    14.         Event e = Event.current;
    15.      
    16.         if (e.type == EventType.MouseDown && e.button == 1 && position.Contains(e.mousePosition)) {
    17.          
    18.             activeProperty = property;
    19.             GenericMenu context = new GenericMenu ();
    20.          
    21.             context.AddItem (new GUIContent ("Expand"),    property.isExpanded, Expand);
    22.             context.AddItem (new GUIContent ("Unexpand"), !property.isExpanded, Unexpand);
    23.          
    24.             context.ShowAsContext ();
    25.         }
    26.  
    27.         /*...
    28.         Actually draw the property
    29.         ... */
    30.          
    31.     }//
    32.  
    33.  
    34. } // END Drawer
    35.  
    I noticed a small oddity though.
    If I use the context menu to change the SerializedProperty actual value, everything works perfectly. However, if a menu entry does nothing but changing the value of
    property.isExpanded
    , (like the code above), the inspector will actuall struggle to reflect these changes : sometimes it will take a small second to update, sometimes it won't update until I interact with it again, sometimes it flashes between 'expanded' and 'not expanded' for a moment before stabilizing... It can get even funkier when fiddling with more than one property in the inspector.
    I tried several tricks to try and force the inspector to repaint immediatly, but no luck.
    Any idea what's causing this ?
     
    Last edited: Aug 4, 2018
  4. PsyKaw

    PsyKaw

    Joined:
    Aug 16, 2012
    Posts:
    86
    You have to call property.serializedObject.Update() before changing property and call property.serializedObject.ApplyModifiedProperties() after.
     
    karl_jones likes this.
  5. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    279
    Not for property drawers. That logic wraps the inspector GUI on a custom editor. If you put it in a property drawer it would at best do nothing and at worst cause state issues.

    You might try using
    EditorGUI.BeginProperty
    and
    EditorGUI.EndProperty
    , but I wouldn't be surprised if that doesn't work since the callback for the context menu is not synchronous with the GUI method.
     
  6. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    2,897
    If you are using a context menu then the Update and Apply will be missed as it's not done inline with PropertyDrawer code, menus are executed at a different time. Calling Apply inside the menu is fine and should solve the issues.
     
    Madgvox likes this.
  7. Madgvox

    Madgvox

    Joined:
    Apr 13, 2014
    Posts:
    279
    When you put it like that it seems bloody obvious that that'd be the case. I don't know why that didn't occur to me!
     
    karl_jones likes this.