• 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
0
Question by vtclayton · Mar 09, 2019 at 01:35 AM · editorguipropertydrawerfoldout

How can PropertyDrawer with fouldouts to draw at the appropriate height?

I'm trying to create a PropertyDrawer with a foldout. I've got something that mostly works, but there's a slight bug. What's happening is that the height is calculated correctly for the number of objects and whether it's expanded, but when the foldout gets changed in OnGUI, the PropertyHeight has already been calculated by GetPropertyHeight— so it's not drawn accurately until the next event that causes a redraw (click, hover, etc.)

⠀

Here's an example of what I'm talking about: Here's an example of what I'm talking about

⠀

How can I get inspectors that use this PropertyDrawer to draw at the appropriate height without lagging behind by a redraw event?

⠀

It seems to me that what I want to do is just trigger a redraw (mark something as dirty? call repaint directly?) from my OnGUI, but I don't know what I'm looking for to do that. I found a suggestion elsewhere to call Editor.Repaint(), but I don't seem to have an Editor available to call that on.

⠀

Alternatively: I'm doing everything wrong and there's an easier way. (Oh, as a caveat, I don't think I can use EditorGUILayout here because of some complexities that I've removed from this simple case)

⠀

Here's the gist of the code:

 [CustomPropertyDrawer(typeof(MyClass))]
 public class MyClassPropertyDrawer : PropertyDrawer
 {
     // ... other functions

     public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
     {
         Rect foldRect = MyCalcFoldRect(position, label);
       
         EditorGUI.BeginProperty(position, label, property);
         property.isExpanded = EditorGUI.Foldout(foldRect, property.isExpanded, label);

         if (property.isExpanded)
         {
             bool wasEnabled = GUI.enabled;
             GUI.enabled = false;
             EditorGUI.indentLevel++;

             var _relatedObjs = MyGetObjects(property);
             Rect rect = MyInitListRect(position);
             foreach (var gob in _currentTargetObjects)
             {
                 rect = MyUpdateListRect(rect);
                 EditorGUI.ObjectField(rect, gob, typeof(GameObject), allowSceneObjects: true);
             }

             GUI.enabled = wasEnabled;
             EditorGUI.indentLevel--;
         }

         EditorGUI.EndProperty();
     }

     public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
     {
         if (property.isExpanded)
         {
             return EditorGUIUtility.singleLineHeight + // the foldout
                 (MyGetObjects(property).Length) *      // for each related obj:
                 (EditorGUIUtility.singleLineHeight + EditorGUIUtility.standardVerticalSpacing);
         }
         else
         {
             return EditorGUIUtility.singleLineHeight;
         }
     }
 }
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

3 Replies

· Add your reply
  • Sort: 
avatar image
0
Best Answer

Answer by vtclayton · Mar 10, 2019 at 01:07 AM

Thanks, silvematt, for putting me on the right path with EditorUtility.SetDirty. I just had to figure out how to get at the target object:

⠀

 EditorUtility.SetDirty(property.serializedObject.targetObject);

⠀

did the trick to force the repaint.

⠀

(I also used EditorGUI.EndChangeCheck to only force the repaint when needed.)

Comment
Add comment · 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
2

Answer by silvematt · Mar 09, 2019 at 02:43 AM

After

 EditorGUI.EndProperty();

Write:

 EditorUtility.SetDirty(target);

This will force the Repaint.

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 vtclayton · Mar 10, 2019 at 12:57 AM 0
Share

I'm afraid I don't understand. I don't have an object called target: this is in a PropertyDrawer, not a Custom Editor.

The function expects a UnityEngine.Object, but I just have the SerializedProperty, which is one of the rare Unity classes that doesn't descend from that.

avatar image
1

Answer by mandisaw · Nov 23, 2020 at 12:04 AM

Just a heads-up for anyone who comes along later, EditorGUI.BeginFoldoutHeaderGroup (and EditorGUI.EndFoldoutHeaderGroup) will accomplish the same effect, including handling any internal SetDirty calls.

The style is slightly different (Header/Bold instead of normal label text), but that can be overridden with GUIStyle objects as desired.

Cheers!

Comment
Add comment · 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

The best place to ask and answer questions about development with Unity.

To help users navigate the site we have posted a site navigation guide.

If you are a new user to Unity Answers, check out our FAQ for more information.

Make sure to check out our Knowledge Base for commonly asked Unity questions.

If you are a moderator, see our Moderator Guidelines page.

We are making improvements to UA, see the list of changes.



Follow this Question

Answers Answers and Comments

101 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

EditorGUI.Foldout consumes click so GUI.Button doesnt work when inside of foldout region. 1 Answer

Property Drawer and Children 3 Answers

EditorGUI.Foldout -- Cannot interact with contents! 1 Answer

Why is my property drawer not drawing on the next line? 1 Answer

Using EditorGUI.ObjectField in PropertyDrawer 0 Answers

  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges