Search Unity

Bug 'Nested' CustomPropertyDrawer not being created

Discussion in 'UI Toolkit' started by FrankvHoof, Feb 23, 2021.

  1. FrankvHoof

    FrankvHoof

    Joined:
    Nov 3, 2014
    Posts:
    258
    I have a custom PropertyDrawer that I am using for a custom Velocity-struct.
    I'm using this struct in a ScriptableObject, and when I create a PropertyField in the Editor for this ScriptableObject the PropertyDrawer works just fine.
    However: I'm also nesting the Inspector for this ScriptableObject inside of the Editor for another ScriptableObject. Inside of that editor, the PropertyField is not rendered at all. The nested Inspector is drawed by calling CreateEditor(asset).CreateInspectorGUI()


    Above you can see the difference between the Nested (left) and Normal (right) inspectors.

    If I check the layout through the UIToolkit Debugger, I can see that the Propertyfield is completely empty.

    Above: Nested Inspector. Below: Regular Inspector


    I'm able to work around the issue by manually calling new VelocityPropertyDrawer().CreatePropertyGUI() instead of using a PropertyField,
    but this seems like a bug in UITookit itself.
     
  2. axeldubillet

    axeldubillet

    Unity Technologies

    Joined:
    Nov 19, 2020
    Posts:
    13
    hello FrankvHoof. could you please let me know which version of Unity you are using?
     
  3. FrankvHoof

    FrankvHoof

    Joined:
    Nov 3, 2014
    Posts:
    258
    @axeldubillet I'm able to reproduce this on both Unity 2020.1.17f1 and 2020.2.1f1 with Unity UI 1.0.0 and UI Builder 1.0.0-preview.12
     
  4. axeldubillet

    axeldubillet

    Unity Technologies

    Joined:
    Nov 19, 2020
    Posts:
    13
    @FrankvHoof https://forum.unity.com/threads/adding-property-field-to-root-after-createinspectorgui.788402/ might be of help.

    in your case, note that the automatic
    Bind()
    call in the Inspector will always Bind the entire inspector GUI to the same (currently selected) GameObject. since you add a nested Inspector for a Object, all of that UI will still try to
    Bind()
    to the active GO, so you need to call
    Bind(nestedObject)
    explicitly, after the main
    Bind()
    , on your nested Object Inspector root to rebind to the correct Object.
    you should do this after the main
    Bind()
    by using the
    GeometryChangeEvent 
    (registered once on your root inspector element and then unregistered)
     
  5. FrankvHoof

    FrankvHoof

    Joined:
    Nov 3, 2014
    Posts:
    258
    @axeldubillet
    "all of that UI will still try to Bind() to the active GO"
    Why would it try to Bind() to an active GO if I'm creating it by calling CreateEditor(childObject).CreateInspectorGUI()? Shouldn't that just directly call the CreateInspectorGUI of my Editor-Script?

    Furthermore: My nested ScriptableObject is rendering just fine. It's the PropertyDrawer inside of that object that isn't showing up. If I draw that with 'new PropertyField(childProp)' it doesn't work, but if I do that with 'new MyPropertyDrawer().CreatePropertyGUI(childProp)' it works fine.
    If I open the Editor for the nested ScriptableObject, it also renders fine.

    It seems like Unity just isn't loading the MyPropertyDrawer? (As in it doesn't know which PropertyDrawer to render when using 'new PropertyField()')
     
  6. FrankvHoof

    FrankvHoof

    Joined:
    Nov 3, 2014
    Posts:
    258
    Hmm.. Somehow adding an additional .BindProperty() does seem to resolve it.

    This Works:
    Code (CSharp):
    1. PropertyField velocityField = new PropertyField(serializedObject.FindProperty("movementVelocity"));
    2. velocityField.BindProperty(serializedObject.FindProperty("movementVelocity"));
    3. velocityContainer.Add(velocityField);
    This Doesn't:
    Code (CSharp):
    1. PropertyField velocityField = new PropertyField(serializedObject.FindProperty("movementVelocity"));
    2. velocityContainer.Add(velocityField);
    Edit: Small addition to this: All of this is being called from the initial CreateInspectorGUI(). It's not being handled in a button-callback or similar event.
     
  7. swankywu

    swankywu

    Joined:
    May 1, 2014
    Posts:
    3
    hi, @axeldubillet. I got a problem that mixing imgui and ui kit.
    Code (CSharp):
    1. //...
    2.         public override void OnInspectorGUI()
    3.         {
    4.             //UnityEngine.Localization.SmartFormat.GlobalVariables
    5.             var fp = this.serializedObject.FindProperty("GlobalVariablesGroup");
    6.             var editor = Editor.CreateEditor(fp.objectReferenceValue);
    7.             editor.OnInspectorGUI();
    8.         }
    9.  
    10. //..
    the GlobalVariablesGroup is drawn by ui kit. So like to what you said above, I need to rebind to the
    SerializedObject again, but how do I bind it inside the OnInspectorGUI method. I can not override the
    CreateInspectorGUI method, since there is a call chain on my end.
     

    Attached Files: