Search Unity

Question Is it possible to use "FillDefaultInspector" in an Overlay script?

Discussion in 'UI Toolkit' started by DoctorShinobi, Oct 24, 2022.

  1. DoctorShinobi

    DoctorShinobi

    Joined:
    Oct 5, 2012
    Posts:
    219
    I'm trying to create a "command list" editor which would allow you to select commands in the regular inspector, and show the currently selected command's properties inside an overlay in the SceneView.

    The problem is InspectorElement.FillDefaultInspector requires an Editor parameter, which Overlay seems to not inherit from.
    Is there any other way to display a default inspector inside an overlay window?
     
  2. oscarAbraham

    oscarAbraham

    Joined:
    Jan 7, 2013
    Posts:
    431
    I think it still works if you pass null as the editor.
     
  3. DoctorShinobi

    DoctorShinobi

    Joined:
    Oct 5, 2012
    Posts:
    219
    Thanks.
    While it does seem to create the elements, it appears they're invisible.

    I'm trying to show an inspector for this WaitCommand.Data class:
    upload_2022-10-25_10-42-29.png

    The Wait.Data object is inserted into the overlay via the Show function:
    upload_2022-10-25_10-46-28.png

    Using the UIToolkit debugger I can confirm the inspector elements are created and inserted into the root element:
    upload_2022-10-25_10-54-16.png

    But it seems like they're not visible nor interactable? I tried forcing their height to be non 0 through the debugger, but they still wouldn't show up.

    Am I missing something very basic here, or is it the result of using "null" in the editor parameter?
     

    Attached Files:

    Last edited: Oct 25, 2022
  4. DoctorShinobi

    DoctorShinobi

    Joined:
    Oct 5, 2012
    Posts:
    219
    I realized InspectorElement can also be instantiated and used with a constructor, so I tried that instead:
    upload_2022-10-25_11-32-9.png

    Now I can properly see the labels of the inspector, but not the fields that let me edit their values
    upload_2022-10-25_11-32-17.png
     
  5. xaku

    xaku

    Joined:
    Jul 19, 2016
    Posts:
    2
    I also had the problem that the PropertyFields generated by InspectorElement.FillDefaultInspector() were not visible and found a fix for it.
    Maybe it will still help someone.

    When looking at the constructor of PropertyField(SerializedProperty property) it says:
    "Providing a SerializedProperty in the construct just sets the bindingPath. You will still have to call Bind() on the PropertyField afterwards."

    It seems like the FillDefaultInspector() method doesn't do this and just creates a new PropertyField by passing the SerializedObject.

    I fixed this by calling a method afterwards that calls Bind() on every PropertyField in a VisualElement.

    Code (CSharp):
    1. _container = root.Q<VisualElement>("container");
    2. var dataSo = new SerializedObject(_selectedData);
    3.  
    4. InspectorElement.FillDefaultInspector(_container, dataSo, null);
    5. SetPropertyFieldBindings(_container, dataSo);
    Code (CSharp):
    1. public static void SetPropertyFieldBindings(VisualElement container, SerializedObject serializedObject)
    2. {
    3.     var propertyFields = container.Query<PropertyField>().ToList();
    4.     foreach (var propertyField in propertyFields)
    5.     {
    6.         propertyField.Bind(serializedObject);
    7.     }
    8. }
     
    Last edited: May 31, 2023
    DoctorShinobi likes this.
  6. griendeau_unity

    griendeau_unity

    Unity Technologies

    Joined:
    Aug 25, 2020
    Posts:
    248
    Binding the root
    container
    should be enough, no need to Query all fields. The editor binding system will go through the hierarchy under it and bind every element with a bindingPath, so all the
    PropertyField
    .
     
    DoctorShinobi likes this.
  7. xaku

    xaku

    Joined:
    Jul 19, 2016
    Posts:
    2
    Thank you, I didn't notice it at first.
    Calling Bind() on the root container directly worked too.

    Code (CSharp):
    1. InspectorElement.FillDefaultInspector(_container, dataSo, null);
    2. _container.Bind(dataSo);
     
    Last edited: May 31, 2023