Search Unity

UIElements custom property drawers?

Discussion in 'UI Toolkit' started by CraigGraff, Sep 15, 2019.

  1. CraigGraff

    CraigGraff

    Joined:
    May 7, 2013
    Posts:
    44
    As far as I can tell these are nonfunctional right now.

    Is this actually the case or am I missing something?
    Is there an expected time when these will work?

    (I tested the example project in 2019.2.5 as well as 2019.3.0b3, but the UIElementsCustomDrawer seems to just be inheriting from ImguiCustomDrawer and not actually doing anything.)

    (I am aware of a hack workaround to make a custom editor for any class that has UIElements property drawers.)
     
    Last edited: Sep 15, 2019
  2. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    I assume you're referring to the Unite LA example. The UIElementsCustomDrawer inherits from ImguiCustomDrawer because it implements one additional override:
    CreatePropertyGUI()

    The way it works is if the
    CustomDrawer
    implements the IMGUI
    OnGui()
    , the system will use it, but if it implements the UIElements
    CreatePropertyGUI()
    , it will ignore the IMGUI UI and use pure UIElements. I just used ImguiCustomDrawer as my base to get the existing functionality but you don't need to do something like that (nor should you).

    There's a more pure example in our scripting docs here:
    https://docs.unity3d.com/ScriptReference/PropertyDrawer.html

    One more thing, and this is probably why you don't see them working right now. UIElements is not yet the default for creating default inspectors. That is, if no custom inspector is defined for a type, it will use IMGUI to generate its inspector. UIElements cannot be embedded inside IMGUI (only the other way around), so any custom UIElements property drawers will not work in a default IMGUI inspector. You have to create a custom UIElements inspector for your MonoBehaviour first. This will be fixed at some point.
     
    Last edited: Sep 17, 2019
    andrew-lukasik likes this.
  3. CraigGraff

    CraigGraff

    Joined:
    May 7, 2013
    Posts:
    44
    Thank you for the clarification!

    I'm glad to hear this is being worked on, because until this is done my initial assessment seems to be correct (effectively if not technically).

    Hopefully this is something that can make it into the 2019 cycle.
     
  4. Ruchir

    Ruchir

    Joined:
    May 26, 2015
    Posts:
    934
    Is this fixed now?

    It still doesn't seem to work for me in unity 2022.1.0f1
     
  5. JoNax97

    JoNax97

    Joined:
    Feb 4, 2016
    Posts:
    611
    I believe they've started to use UI toolkit as a default for inspectors in 2022.2
     
    marcospgp, martinpa_unity and Ruchir like this.
  6. uDamian

    uDamian

    Unity Technologies

    Joined:
    Dec 11, 2017
    Posts:
    1,231
    Indeed. This should no longer be an issue in 2022.2+
     
    marcospgp and Thimo_ like this.
  7. OMGeeky

    OMGeeky

    Joined:
    Sep 5, 2018
    Posts:
    17
    Im currently testing it with 2022.2.0a17 and it seems my PropertyDrawer gets completly ignored. Im pretty sure I got everything in there what I need but it just shows the default PropertyDrawer.

    Just to be sure maybe someone can check it...
    My PropertyDrawer (that gets ignored):
    Code (CSharp):
    1. [CustomPropertyDrawer( typeof(TestAttribute) )]
    2. public class TestDrawer : PropertyDrawer
    3. {
    4.     public override VisualElement CreatePropertyGUI( SerializedProperty property )
    5.     {
    6.         var container = new VisualElement();
    7.         container.Add( new Button( () => Debug.Log( "test UiElements" ) ) { text = "ui button" } );
    8.         return container;
    9.     }
    10.  
    11.     public override void OnGUI( Rect position , SerializedProperty property , GUIContent label )
    12.     {
    13.         var res = GUI.Button( position , "test" );
    14.         if ( res )
    15.         {
    16.             Debug.Log( "test" );
    17.         }
    18.     }
    19. }
    My Attribute:
    Code (csharp):
    1. [AttributeUsage( AttributeTargets.Field )]
    2. public class TestAttribute : Attribute { }
    and my MonoBehaviour:
    Code (CSharp):
    1. public class TestMb : MonoBehaviour
    2. {
    3.     [SerializeField , Test] int shouldBeReplacedByAButton = 4;
    4. }
    I would expect the int field to be completly replaced by a button but nothing happens and it just shows the normal name and value:
    upload_2022-7-24_19-2-38.png

    Am I doing something wrong or should I post a Bug Report?
     
  8. billykater

    billykater

    Joined:
    Mar 12, 2011
    Posts:
    329
    You need to derive from PropertyAttribute for any Attribute based PropertyDrawer to work.
     
    uDamian likes this.
  9. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    613
    As UI Toolkit seems to be the future, I'm doing my best to adopt it. However, I'm having trouble with indentation of PropertyDrawers, as it doesn't seem to be respected.

    Screenshot 2023-01-07 213227.png
    Indentation of custom property drawer using uxml is off.

    How may I achieve proper indentation using uxml? I use PropertyDrawers extensively and have always preferred their reusability over drawing Editors.
     
  10. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    Hi! You can make fields that inherit from BaseField use the desired label width by adding BaseField<T>.alignedFieldUssClassName to them.
     
    CaseyHofland likes this.
  11. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    613
    Thanks, that made it look perfect! Weird that it isn't part of elements by default though, it seems like such a slam dunk.

    I still have trouble with PropertyAttributes, and I can't really find much about it on the internet. Are they still part of the architecture?

    A simple test like this doesn't work:
    Code (CSharp):
    1. //pseudo-code
    2. [ReadOnly] public float f;
    3.  
    4. public override VisualElement CreatePropertyGUI(SerializedProperty property)
    5. {
    6.     var root = new PropertyField(property);
    7.  
    8. root.AddToClassList(VisualElement.disabledUssClassName);
    9.     return root;
    10. }
    If I'd still like to add code via Attributes, how would I go about it?
     
  12. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    Using property drawers with attributes does work. It's the same steps as in IMGUI. The only thing I see wrong with that code is that the proper way to disable elements is to use the SetEnabled method. There may be other things to find with complete example code for an attribute and a drawer.
     
  13. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    613
    Hrmm it's still not working.

    I'm gonna post some code: just focus on
    _max
    .
    ReadOnly.png

    ReadOnlyDrawer.png

    _max
    has
    ReadOnlyAttribute
    applied but I'm still able to change
    _max
    .

    Perhaps it is because
    FloatParameter
    has its own property drawer. The UI for it has been created using UI Builder and looks like this:
    FloatParameter.png

    I'd hope this wouldn't override any attributes, as it would kind of mess up my workflow. But I dunno, maybe this is a bug?

    Hopefully I'm just missing something really obvious, but right now the ReadOnlyDrawer never gets triggered (even if I give it a Debug.Log())

    -----------

    All that said, I really appreciate you helping me out! I hope to fully adopt UI Elements in the future and I am grateful for your help through my awkward first steps.
     
  14. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    Hm... I don't see anything obvious. It shouldn't matter that FloatParameter has its own drawer. Does ReadOnlyAttribute inherit from PropertyAttribute? Just to help diagnosing this problem, is ReadOnlyDrawer.CreatePropertyGUI being called? Could you put some Debug.Log or breakpoints there to see if it's being used?

    :) No problem. I'm happy to help!
     
    CaseyHofland likes this.
  15. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    OH! I see what it is! In the Builder, you are using a FloatField for max. To use PropertyDrawers, you need to use PropertyFields.
     
    CaseyHofland likes this.
  16. CaseyHofland

    CaseyHofland

    Joined:
    Mar 18, 2016
    Posts:
    613
    Aaaaah dayum, that's a gotcha if I ever saw one. Thanks that worked instantly!

    Thank you so much for your help! It's honestly amazing how easy it is to make UI with the UI Builder. Those were all my pet peeves: consider me converted!
     
    oscarAbraham likes this.
  17. Ruchir

    Ruchir

    Joined:
    May 26, 2015
    Posts:
    934
    I'm still getting No GUI Implemented in the 2023.1.0b1 version when I try to create custom Drawers with UI Toolkit.
    Was something changed during the 2023 cycle?

    EDIT: I found out that having odin Inspector in my project prevents me from using UIElements in property drawers for some reason
     
    Last edited: Feb 4, 2023
  18. jeffreymlynch

    jeffreymlynch

    Joined:
    Jun 27, 2017
    Posts:
    12
    Indeed, I ran into this issue as well. Odin and UI Toolkit really need to play nice together soon.
     
    Ruchir likes this.
  19. Tor-Vestergaard

    Tor-Vestergaard

    Joined:
    Mar 20, 2013
    Posts:
    188
    To give an update on this issue re: Odin, Odin now has a feature preview build available that adds support for rendering UI Toolkit visual elements inline, embedded inside its normal IMGUI editor context. This works in 2020.3 and above. So if anybody else is struggling with this, come on our Discord and ask to try it out and we'll get you set up. We will likely be making the preview generally available on our website soon, and launch it in an actual stable release within a few months.
     
    Mnemotic and TWolfram like this.