Best way to get collections to draw using the now default reorderable drawer?

Hey there,
I was wondering if anyone could share the best way to go about getting collections to draw using the ReorderableList drawer when using a “Default UIElements CustomEditor Drawer”?

I spent a bunch of time trying to make the few dictionaries I had look good with a custom drawer which required me to make the CustomEditors derive from a UIElements default inspector, only to now basically have the rest of the inspectors look much better in debug mode/view, because all the list and arrays look nice.

I would imagine that within the loop below I could get the collections by name, I am just not sure what I would have to do to them from there to use the current list drawer?

Default Inspector

[CustomEditor(typeof(Object), true, isFallback = true)]
[CanEditMultipleObjects]
public class DefaultEditorDrawer : Editor
{
    public bool showScript = false;
    public List<string> excludedFields = new List<string>();

    public override VisualElement CreateInspectorGUI()
    {
        var root = new VisualElement();

        var property = serializedObject.GetIterator();
        if (property.NextVisible(true)) // Expand first child.
        {
            do
            {
                var field = new PropertyField(property) {name = "PropertyField:" + property.propertyPath};

                if (property.propertyPath == "m_Script" && serializedObject.targetObject != null)
                {
                    if (showScript) field.SetEnabled(false);
                    else continue;
                }

                if (excludedFields.Contains(property.propertyPath) && serializedObject.targetObject != null)
                {
                    continue;
                }

                root.Add(field);
            } while (property.NextVisible(false));
        }

        return root;
    }
}

Thanks,
-MH

Ok, I was able to get this worked out. Using the following, with the addition of a SerializedPropery extension method to determine if a property is an appropriate collection, it creates an IMGUI reorderable list out of it.

The “excluded fields” part can be omitted, I just used it to filter out fields from being drawn.

Default UIElements Drawer

[CustomEditor(typeof(Object), true, isFallback = true)]
[CanEditMultipleObjects]
public class DefaultEditorDrawer : Editor
{
    public bool showScript;
    public List<string> excludedFields = new List<string>();
    string m_IMGUIPropNeedsRelayout;
    ScrollView m_ScrollView;

    public override VisualElement CreateInspectorGUI()
    {
        var root = new VisualElement();
        var property = serializedObject.GetIterator();
        m_ScrollView = new ScrollView();
        root.Add(m_ScrollView);
        if (property.NextVisible(true)) // Expand first child.
        {
            do
            {
                var field = new PropertyField(property) {name = "PropertyField:" + property.propertyPath};
                if (property.propertyPath == "m_Script" && serializedObject.targetObject != null)
                {
                    if (showScript) field.SetEnabled(false);
                    else continue;
                }

                if (property.IsReallyArray() && serializedObject.targetObject != null)
                {
                    var copiedProperty = property.Copy();
                    var imDefaultProperty = new IMGUIContainer(() =>
                    {
                        DoDrawDefaultIMGUIProperty(serializedObject, copiedProperty);
                    }) {name = property.propertyPath};
   
                    m_ScrollView.Add(imDefaultProperty);
                    continue;
                }

                if (excludedFields.Contains(property.propertyPath) && serializedObject.targetObject != null)
                {
                    continue;
                }

                root.Add(field);
            } while (property.NextVisible(false));
        }

        foreach (var foldout in m_ScrollView.Query<Foldout>().ToList())
        {
            foldout.RegisterValueChangedCallback(e =>
            {
                var fd = e.target as Foldout;
                if (fd == null) return;
                var path = fd.bindingPath;
                var container = m_ScrollView.Q<IMGUIContainer>(name: path);
                RecomputeSize(container);
            });
        }

        return root;
    }

    private void RecomputeSize(IMGUIContainer container)
    {
        if (container == null) return;
        var parent = container.parent;
        container.RemoveFromHierarchy();
        parent.Add(container);
    }

    public void DoDrawDefaultIMGUIProperty(SerializedObject serializedObject, SerializedProperty property)
    {
        EditorGUI.BeginChangeCheck();
        serializedObject.Update();
        bool wasExpanded = property.isExpanded;
        EditorGUILayout.PropertyField(property, true);
        if (property.isExpanded != wasExpanded) m_IMGUIPropNeedsRelayout = property.propertyPath;
        serializedObject.ApplyModifiedProperties();
        EditorGUI.EndChangeCheck();
    }
}

Extension:

Used property Extension Method

public static class PropertyExtensions
{
    public static bool IsReallyArray(this SerializedProperty property)
    {
        return property.isArray && property.propertyType != SerializedPropertyType.String;
    }
}