PropertyDrawer for Array
I'm trying to write a custom property drawer to change the display names of my array items, however whatever I do, I get a ArgumentException: Getting control 19's position in a group with only 19 controls when doing Repaint Error I saw that this is supposedly related to changing values of your array mid update, but I ma not doing anything of that sort so I am very much puzzled
[CustomPropertyDrawer(typeof(WarenContainer))]
public class WarenContainerEditor : PropertyDrawer
{
// Draw the property inside the given rect
public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
{
EditorGUI.BeginProperty (position, label, property);
SerializedProperty list = property.FindPropertyRelative ("Values");
int max = list.arraySize - 1;
EditorGUI.indentLevel += 1;
for (int i = 0; i < max; i++) {
string name = "";
if (i < (int)Ware.END)
name = ((Ware)i).ToString ();
EditorGUILayout.PropertyField(list.GetArrayElementAtIndex(i), new GUIContent (name));
}
EditorGUI.indentLevel -= 1;
EditorGUI.EndProperty ();
}
}
Values is an array of ints and Ware is an enum containing the names. Can anyone help me where this fails?
Answer by Whitecold · Sep 25, 2017 at 06:13 PM
So, after much trying I found out that there are two PropertyField Functions, one in EditorGUI and one in EditorGUILayout. Using EditorGUI is safe, and does not cause the ArgumentException error
Answer by Arsonistic · Jan 18, 2019 at 11:48 AM
The exception you're encountering is due to changing the number of elements to draw between UI Layout and Repaint events. The Layout event gathers data about element positioning and the Repaint event then uses that data to paint (draw) the elements. If data is changed during the Layout event it likely will not be sent to the Repaint event, causing a data-missmatch between the two. To avoid this you can make sure to only manipulate the array data during the Repaint event.
Just use this line of code and you should be fine:
if (Event.current.type == EventType.Repaint){
//Manipulate array
}