SerializedObject.FindProperty() on a 2D array of bools returns null

Viewed 1072

I'm currently working on a custom editor in Unity for a class that has a 2D array of bools that need to be set. However, whenever I try to set the values using SerializedObject.FindProperty() the returned value is null and I get errors. When I try to set them directly through SerializedObject.targetObject the bools only change for that call of OnGui() and don't save when I call SerializedObject.ApplyModifiedProperties() because it has know way of knowing they were changed.

private void OnGUI()
{
    serializedObject.Update();

    GUILayout.Label(serializedObject.targetObject.name + " - Spawn Options", EditorStyles.boldLabel);

    EditorGUIUtility.labelWidth = 60;
    indexSize = EditorGUILayout.DelayedIntField(new GUIContent("Array Size"), indexSize, GUILayout.ExpandWidth(false));

    serializedObject.FindProperty("gameObjects").arraySize = indexSize;
    LevelGenerator target = (LevelGenerator)serializedObject.targetObject;
    target.spawnLocations = new bool[indexSize, target.areas.Count];

    EditorGUILayout.Space();


    for (int i = 0; i < indexSize; i++)
    {
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.ObjectField(serializedObject.FindProperty("gameObjects").GetArrayElementAtIndex(i));

        var labels = target.areas.Keys;
        for(int j = 0; j < target.areas.Count; j++)
        {
            target.spawnLocations[i, j] = EditorGUILayout.Toggle(labels.ElementAt(j), target.spawnLocations[i, j]);

            if(target.spawnLocations[i, j])
            {
                Debug.Log("set for one loop at least");
            }

            EditorGUILayout.PropertyField(
                serializedObject.FindProperty("spawnLocations").GetArrayElementAtIndex(i).GetArrayElementAtIndex(j), 
                new GUIContent(labels.ElementAt(j)));
        }

        EditorGUILayout.EndHorizontal();
    }

    serializedObject.ApplyModifiedProperties();
}

This is my first question on StackOverflow and I tried to follow the guidelines as well as possible but if I made any mistakes in the question I apologize.

1 Answers

It seems the reason why it's null is limitations of serialized properties in Unity. If the property is an array of ints for example, it references the first element in SerializedProperty.intValue and has isArray, arraySize, etc to let you know it is actually an array. This falls apart when it's an array of arrays. So the best solution I could find was treating a one-dimensional array like a two-dimensional one which isn't very elegant but data structures are pretty abstract anyway. So again, as a warning to anyone who has had the same problem, the API says arrays are all good but it means 1D arrays.

Related