Custom Property Drawer values unchangeable in inspector

So I have been going in circles with this for a few hours now. I am new to writing my own Custom Inspector items and am not even sure if this is the best approach. My problem is that I can’t edit the values of Solution in the inspector. They just always hold the value of 0.

Any help would be greatly appreciated.

Here is my Custom Property Drawer for my Solution class. It is essentially a 2D array.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

[CustomPropertyDrawer(typeof(LevelGenerator.Solution))]
public class SolutionPropertyDrawer : PropertyDrawer {

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        label = EditorGUI.BeginProperty(position, label, property);
        Rect contentPosition = EditorGUI.PrefixLabel(position, label);
        float xStart = contentPosition.x;
        EditorGUI.indentLevel = 2;  
        property.isExpanded = EditorGUI.Foldout(position, property.isExpanded, label);
        EditorGUI.indentLevel = 0;
        contentPosition.width = 23f;
        contentPosition.height = 16f;
        if(property.isExpanded)
        {
            SerializedProperty rows = property.FindPropertyRelative("rows");
            for(int i = 0; i < rows.arraySize; i++)
            {
                SerializedProperty row = rows.GetArrayElementAtIndex(i).FindPropertyRelative("row");
                for(int j = 0; j < row.arraySize; j++)
                {  
                    EditorGUI.PropertyField(contentPosition,row.GetArrayElementAtIndex(j), GUIContent.none);
                    contentPosition.x += 25f;
                }
                contentPosition.x = xStart;
                contentPosition.y += 20f;
            }
        }
      
        EditorGUI.EndProperty();
      
    }

    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        if(property.isExpanded)
        {
            SerializedProperty rows = property.FindPropertyRelative("rows");
            return rows.arraySize * 20f;
        }
        return 18f;
    }
}

And here is the code for the Solution class

[System.Serializable]
    public class Solution{

        [System.Serializable]
        public class rowData
        {
            public int[] row;

            public rowData(int size)
            {
                row = new int[size];
            }
        }

        public rowData[] rows;

        public int this[int rowIndex, int colIndex]
        {
            get { return rows[rowIndex].row[colIndex]; }
            set { rows[rowIndex].row[colIndex] = value; }
        }

        public Solution(int sizeX, int sizeY)
        {
            rows = new rowData[sizeY];
            for(int i = 0; i < sizeY; i++)
            {
                rows[i] = new rowData(sizeX);
            }
        }
    }

EDIT - SOLUTION
So I figured out what I did wrong. Thanks to methos5K for giving a hand in figuring out what I was doing! So the issue seems to be with .isExpanded. I’m not sure if I wasn’t using it correctly but it seemed to stop me being able to edit the fields. I have made some changes to the code and cleaned out anything unnecessary. I added some comments as well.
I’m not sure if this is the best method of achieving what I wanted but it works!

using UnityEngine;
using UnityEditor;

[CustomPropertyDrawer(typeof(LevelGenerator.Solution))]
public class SolutionPropertyDrawer : PropertyDrawer {

    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        //Set the label
        EditorGUI.PrefixLabel(position, label);
        //Set the indent level so it matches the inspector
        EditorGUI.indentLevel = 2;
        //Set the indentLevel back to 1 for the individual boxes of the 2D array.
        EditorGUI.indentLevel = 0;
        //Set the height of the individual boxes, and the x offset from the label.
        position.x += 170f; // I just adjusted this number until the boxes lined up.
        float xStart = position.x;
        position.width = 23f;
        position.height = 16f;
        //Find the Rows property of Solution, and interate through them
        SerializedProperty rows = property.FindPropertyRelative("rows");
        for(int i = 0; i < rows.arraySize; i++)
        {
            //From each column in each row and iterate through them.
            SerializedProperty row = rows.GetArrayElementAtIndex(i).FindPropertyRelative("row");
            for(int j = 0; j < row.arraySize; j++)
            {   
                //display the x,y coordinate of the 2D array
                EditorGUI.PropertyField(position,row.GetArrayElementAtIndex(j), GUIContent.none);
                //move the next input box 25 in the x direction.
                position.x += 25f;
            }
            //start a new row, set x back to the far left and increment y to be below the current row.
            position.x = xStart;
            position.y += 20f;
        }
    }

    public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        //increase the size of the property so the array doesn't overlap other labels.
        SerializedProperty rows = property.FindPropertyRelative("rows");
        return rows.arraySize * 20f;
    }
}

Okay, my editor skills are lousy… I tried your code and had a few issues, but I think this is working for me – I am just pasting the relevant section:

label = EditorGUI.BeginProperty(position, label, property);
Rect contentPosition = EditorGUI.PrefixLabel(position, label);
float xStart = contentPosition.x;
EditorGUI.indentLevel = 2;
position.y += 16;
position.height = 16;
property.isExpanded = EditorGUI.Foldout(position, property.isExpanded, label);
EditorGUI.indentLevel = 0;
contentPosition.width = 23f;
contentPosition.height = 16f;

// then, changed the last / default return value
public override float GetPropertyHeight(SerializedProperty property, GUIContent label)
    {
        if (property.isExpanded)
        {
            SerializedProperty rows = property.FindPropertyRelative("rows");
            return rows.arraySize * 20f;
        }
        return 34f;
    }

Not sure if it looks perfect, but I can definitely change values and they’re saved.

1 Like

Initial issue here is that your foldout code

EditorGUI.Foldout(position, property.isExpanded, label);

occupy whole property area. It should be something like this

Rect foldPosition = position;
foldPosition.height = EditorGUIUtility.singleLineHeight;
EditorGUI.Foldout(foldPosition, property.isExpanded, label);