Custom Inspector resets after changes in script

Hi, everyone!
I have a problem for which I haven’t found solution, yet, and I must say - I’ve been searching and searching for weeks and… just nothing, null, nil.

So, cutting to the point. I want to make a custom inspector for my array but whenever I change something in the code (Editor of MonoBehaviour script), even when I just make a space between lines, the size of my array automatically resets to 0.

Here’s my code:

public class GameOptionsScript : MonoBehaviour {
    [SerializeField]
    public GameOption[] gameOptionsBool = new GameOptionBool[0];

}

public class GameOption {
    public string name = "";
    public bool isOn = false;
}

[System.Serializable]
public class GameOptionBool : GameOption {
}

///////////////////////////

[CustomEditor(typeof(GameOptionsScript))]
public class GameOptionsScriptEditor : Editor {

    private bool _unfoldedOptionsBool;

    public override void OnInspectorGUI() {
        GameOptionsScript gameOptionsScript = (GameOptionsScript)target;

        this._unfoldedOptionsBool = EditorGUILayout.Foldout(this._unfoldedOptionsBool, "Game Options Bool");
        if (this._unfoldedOptionsBool) {
            EditorGUI.BeginChangeCheck();
            int size = gameOptionsScript.gameOptionsBool.Length;
            size = EditorGUILayout.IntField("Size:", size);
            if (EditorGUI.EndChangeCheck()) {
                if (size < 0) {
                    Debug.LogError("Trying to set negative size of an array");
                } else {
                    if (size != gameOptionsScript.gameOptionsBool.Length) {
                        int diff = size - gameOptionsScript.gameOptionsBool.Length;
                        int oldSize = gameOptionsScript.gameOptionsBool.Length;
                        GameOption[] gameOptionsBool = new GameOptionBool;
                        int i = 0;
                        if (diff > 0) {
                            for (; i < oldSize; i++) {
                                gameOptionsBool _= gameOptionsScript.gameOptionsBool*;*_

}
for (; i < size; i++) {
gameOptionsBool = new GameOptionBool();
}
gameOptionsScript.gameOptionsBool = gameOptionsBool;
} else if (diff < 0) {
for (; i < size; i++) {
gameOptionsBool = gameOptionsScript.gameOptionsBool*;*
}
gameOptionsScript.gameOptionsBool = gameOptionsBool;
}
}
}

}
}
}
}
I don’t know what I do wrong. I’ve tried SetDirty, ApplyModifiedProperties, various combinations, changes, modifications… but nothing worked.
I hope you will help me with this issue. :C

You have two problems here:

  • GameOption is not “Serializable” because it doesn’t have the “Serializable” attribute.
  • Unity’s serialization system doesn’t support inheritance for custom-serializable-classes. It always serializes a field by it’s declared type, not by it’s content.

So even when you put the Serializable attribute on your GameOption class, after deserialization the array will contain “GameOption” instances and not “GameOptionBool” instances.

So this would actually be serialized:

public class GameOptionsScript : MonoBehaviour
{
    public GameOption[] gameOptionsBool;
}

[System.Serializable]
public class GameOption
{
    public string name = "";
    public bool isOn = false;
}

I’m not sure why you want to implement a custom inspector for that array, but when it comes to arrays of custom serializable classes, most the time it’s way easier to implement a PropertyDrawer for the array’s item type.