Call default constructor for Array elements in a Custom Editor

I have a custom editor in Unity 2019.4 LTS which displays an array of a serializable class not based on Object.

When a new array element is added it doesn’t seem to call my class constructor. How can I do this for a SerializedProperty? My class also has a SetClassDefaults() method but I can’t seem to call that from a SerializedProperty either.

U2022.1+ has SerializedProperty.boxedValue but that doesn’t help with U2019.4.

/// <summary>
/// Draw an array in the inspector with Add/Remove buttons.
/// </summary>
/// <param name="serializedProperty"></param>
/// <param name="labelGUIContent"></param>
/// <param name="labelWidth"></param>
/// <param name="elementName"></param>
/// <param name="buttonCompact"></param>
public static void DrawArray(SerializedProperty serializedProperty, GUIContent labelGUIContent, float labelWidth, string elementName, GUIStyle buttonCompact)
{
    GUILayout.BeginHorizontal();
    EditorGUILayout.LabelField(labelGUIContent, GUILayout.Width(labelWidth - 1f));
    EditorGUILayout.LabelField(serializedProperty.arraySize.ToString("00"), GUILayout.Width(20f));

    if (GUILayout.Button("+", GUILayout.MaxWidth(20f)))
    {
        serializedProperty.arraySize++;

        SerializedProperty element = serializedProperty.GetArrayElementAtIndex(serializedProperty.arraySize - 1);

        // How to call default constructor of serializable class not based on Object???

        Debug.Log("[DEBUG] Element Type " + element.type.ToString());
    }

    if (GUILayout.Button("-", GUILayout.MaxWidth(20f)))
    {
        if (serializedProperty.arraySize > 0) { serializedProperty.arraySize--; }
    }

    GUILayout.EndHorizontal();

    EditorGUI.indentLevel++;

    for (int arrayIdx = 0; arrayIdx < serializedProperty.arraySize; arrayIdx++)
    {
        GUILayout.BeginHorizontal();
        EditorGUILayout.LabelField(elementName + " " + (arrayIdx + 1).ToString(), GUILayout.Width(labelWidth - 16f));
        EditorGUILayout.PropertyField(serializedProperty.GetArrayElementAtIndex(arrayIdx), GUIContent.none);
        GUILayout.EndHorizontal();
    }
    EditorGUI.indentLevel--;
}

Keep googling… this issue has been discussed and brow-beaten into a fine sticky powder all over the internet over the years.

The answer is generally that if you need this, you have to write a custom editor.

Hmm, non-answer responses like this give the forums a bad name in the community. I already have a CustomEditor script. Maybe you mean a custom property drawer??

TIP: If you want to actually help people, a simple link to someone who has provided a viable solution would go a long way (if you don’t have a solution yourself).

1 Like

I’m not googling for you, sorry.

The reason? I don’t have this problem.

But I’ve seen dozens of other posts.

I told you what I’ve seen and what you might expect in the solution.

For others that come across this, here is the solution I arrived at. It’s not pretty but it works.

int _prevArraySize = myarrayProp.arraySize;

EditorHelper.DrawArray(myarrayProp...);

if (myarrayProp.arraySize > _prevArraySize)
{
    serializedObject.ApplyModifiedProperties();
    myComponent.MyArray[myarrayProp.arraySize - 1].SetClassDefaults();
    serializedObject.Update();
}
3 Likes