- Home /
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
trying the above solution with a fixed array of 4 labels for the editor (ins$$anonymous$$d of lement0 etc) but I get an error:
 using UnityEngine;
 using System.Collections;
 using UnityEditor;
 
 listVisibility = true;
 
 [CustomEditor(typeof(buttonImage))]
 public class buttonStateEditor : Editor {
 
     public string StatusNames = new String{
         "inactive",
         "live",
         "selected",
         "pressed",
     };
 
     public override void OnInspectorGUI() {
         serializedObject.Update();
         EditorGUIUtility.LookLikeInspector();
         ListIterator(StatusNames, ref listVisibility);
         serializedObject.Apply$$anonymous$$odifiedProperties();
     }
 
     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--;
         }
     }
 
 }
Answer by steinbitglis · Feb 24, 2012 at 02:04 PM
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
Thanks a lot for answering this. I don't have the time to test this in the near future, but I'll assume this will do the trick, so I'll flag this answer as correct.
Thanks mate!
Thanks, very usefull !
I can't find this on Unity Documentation.
It was a bit difficult to find, but it's EditorGUILayout.PropertyField, or EditorGUI.PropertyField
http://docs.unity3d.com/ScriptReference/30_search.html?q=PropertyField
http://docs.unity3d.com/ScriptReference/EditorGUI.PropertyField.html http://docs.unity3d.com/ScriptReference/EditorGUILayout.PropertyField.html
Thanks for the update about using the includeChildren flag, was exactly what I was looking for! :)
Perhaps this was in 2012, but now(2016) in, the best answer is below by Luna4Dev1. (use showChildren flag in function parameter.)
Answer by Luna4Dev1 · Feb 13, 2015 at 01:23 PM
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.
best answer =). don't know why everyone like first dirty solutions
Answer by termway · Jun 28, 2012 at 10:25 AM
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--;
         }
     }
Your answer
 
 
             Follow this Question
Related Questions
Null SerializedProperty SerializedObject upon Removal from list 1 Answer
Type casting SerializedProperty.objectReferenceValue doesn't work? 3 Answers
How to get fields of a custom script through SerializedProperty.FindPropertyRelative? 1 Answer
