Editor: How to do PropertyField for List elements?

Hi there,

I finally got a array handling with serialized properties working, but I need the same for generic lists. It comes down to to the question of “How to access List.Count and List[dataindex] when using FindProperty()” ???

Here’s my working array code so far:

void ArrayGUI(SerializedObject obj,string name)
    {
        int no = obj.FindProperty(name + ".Array.size").intValue;
        EditorGUI.indentLevel = 3;
        int c = EditorGUILayout.IntField("Size", no);
        if (c != no)
            obj.FindProperty(name + ".Array.size").intValue = c;

        for (int i=0;i<no;i++) {
            var prop = obj.FindProperty(string.Format("{0}.Array.data[{1}]", name, i));
            EditorGUILayout.PropertyField(prop);
        }
    }

Thanks in advance

Jake

Resurrecting this old thread because I always forget the solution and it’s the first hit on Google;

In newer versions of Unity, the PropertyField now has an IncludeChildren flag - simply set that to true and your PropertyField will draw arrays like the default inspector.

DrawDefaultInpector() does something like this:

override def OnInspectorGUI():
    serializedObject.Update()

    EditorGUIUtility.LookLikeInspector()

    myIterator = serializedObject.FindProperty("myArrayField")
    while true:
        myRect = GUILayoutUtility.GetRect(0f, 16f)
        showChildren = EditorGUI.PropertyField(myRect, myIterator)
        break unless myIterator.NextVisible(showChildren)

    serializedObject.ApplyModifiedProperties()

Update:

These days it’s probably better to follow Luna4Dev1’s advice:

In newer versions of Unity, the PropertyField now has an IncludeChildren flag

C# version of steinbitglis answered

public override void OnInspectorGUI()
{
    serializedObject.Update();
    EditorGUIUtility.LookLikeInspector();
    ListIterator("myArrayField");
    serializedObject.ApplyModifiedProperties();
}

public void ListIterator(string listName)
    {
        //List object
        SerializedProperty listIterator = serializedObject.FindProperty(listName);
        Rect drawZone = GUILayoutUtility.GetRect(0f, 16f);
        bool showChildren = EditorGUI.PropertyField(drawZone, listIterator);
        listIterator.NextVisible(showChildren);
    
        //List size
        drawZone = GUILayoutUtility.GetRect(0f, 16f);
        showChildren = EditorGUI.PropertyField(drawZone, listIterator);
        bool toBeContinued = listIterator.NextVisible(showChildren);

        //Elements
        int listElement = 0;
        while (toBeContinued)
        {
            drawZone = GUILayoutUtility.GetRect(0f, 16f);
            showChildren = EditorGUI.PropertyField(drawZone, listIterator);
            toBeContinued = listIterator.NextVisible(showChildren);
            listElement++;
        }

}

Update : I encountered problem with expending and nested list (like Unity crash >_<)

So here a new version which work for me.

 private listVisibility = true;

...
    public override void OnInspectorGUI()
    {
        serializedObject.Update();
        EditorGUIUtility.LookLikeInspector();
        ListIterator("myArrayField", ref listVisibility);
        serializedObject.ApplyModifiedProperties();
    }


 public void ListIterator(string propertyPath, ref bool visible)
    {
        SerializedProperty listProperty = serializedObject.FindProperty(propertyPath);
        visible = EditorGUILayout.Foldout(visible, listProperty.name);
        if (visible)
        {
            EditorGUI.indentLevel++;
            for (int i = 0; i < listProperty.arraySize; i++)
            {
                SerializedProperty elementProperty = listProperty.GetArrayElementAtIndex(i);
                Rect drawZone = GUILayoutUtility.GetRect(0f, 16f);
                bool showChildren = EditorGUI.PropertyField(drawZone, elementProperty); 
            }
            EditorGUI.indentLevel--;
        }
    }