- 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