Why can't I serialize anything with my custom inspector?

So I’ve written a custom inspector for a couple of my classes, to make them more presentable and to show some information mid-game that would otherwise be hidden. Problem is, no matter what I change in the inspector, as soon as I hit “Play” everything snaps back to default values. No matter what I do, nothing works.

Here are two scripts that I’m having problems with.
This is the source code for the class:

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

[Serializable]
public class Skills : MonoBehaviour
{
    public int startingExp = 0;
    public int maxLevel = 100;

    public float expCurveConst = 0.0f;
    public float expCurveScalar = 80.0f;
    public float expCurveSquare = 15.0f;
    public float expCurveCube = 5.0f;
   
    public int ExpReqForLevel(int level)
    {
        return (int)(expCurveConst    +
                     (level * expCurveScalar) +
                     (level * level * expCurveSquare) +
                     (level * level * level * expCurveCube) );
    }
   
   
   
    [SerializeField]
    private int[] _lvl = new int[(int)SkillName.MAX_SKILLS];
    [SerializeField]
    private int[] _exp = new int[(int)SkillName.MAX_SKILLS];
   
    public void Awake()
    {
        for (int i = 0; i < (int)SkillName.MAX_SKILLS; ++i)
        {
            _exp[i] = startingExp;
            UpdateSkill(i);
        }
    }
   
    public int GetLevel(int index)
    {
        return _lvl[index];
    }
   
    public void SetLevel(int index, int value)
    {
        if (value <= 0)
            _exp[index] = 0;
        else if (value >= maxLevel)
            _exp[index] = ExpReqForLevel(maxLevel -1);
        else
            _exp[index] = ExpReqForLevel(value -1);
       
        _lvl[index] = value;
        UpdateSkill(index);
    }
   
    public void GainLevel(int index, int value)
    {
        value = _lvl[index] + value;
       
        if (value <= 0)
            _exp[index] = 0;
        else if (value >= maxLevel)
            _exp[index] = ExpReqForLevel(maxLevel -1);
        else
            _exp[index] = ExpReqForLevel(value -1);
       
        _lvl[index] = value;
        UpdateSkill(index);
    }

    public int GetExp(int skill)
    {
        return _exp[skill];
    }

    public void GainExp(int skill, int expGained)
    {
        _exp[skill] += expGained;
        UpdateSkill(skill);
    }

    public void SetExp(int skill, int newExp)
    {
        _exp[skill] = newExp;
        UpdateSkill(skill);
    }
   
    private void UpdateSkill(int skill)
    {
        // Clean up boundary cases //
        if (_lvl[skill] > maxLevel)
            _lvl[skill] = maxLevel;
        if (_lvl[skill] < 0)
            _lvl[skill] = 0;

        // If we've reached the amount of exp we need, level up! //
        while (_exp[skill] >= ExpReqForLevel(_lvl[skill]) )
        {
            _lvl[skill]++;
        }

        // If our xp is too low for the level we ought to be at, level down :( //
        while ((_lvl[skill] > 0) && (_exp[skill] < ExpReqForLevel(_lvl[skill] -1)))
        {
            _lvl[skill]--;
        }
    }
}

public enum SkillName
{
    Brawling,
    Precision,
    Necromancy,
    Discipline,

    MAX_SKILLS
}

And the corresponding code for the editor:

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

[CustomEditor(typeof (Skills))]
public class SkillsEditor : Editor
{
    bool showskills = true;
    Skills skills;

    void OnEnable()
    {
        skills = (Skills)target;

        if (!Application.isPlaying)
        {
            skills.Awake();
        }
    }

    public override void OnInspectorGUI()
    {   
        skills.startingExp = EditorGUILayout.IntField("Starting EXP", skills.startingExp);
        skills.maxLevel = EditorGUILayout.IntField ("Max Level", skills.maxLevel);

        // The multipliers for the exp-for-level polynomial function. //
        EditorGUILayout.LabelField("EXP Curve");
        EditorGUILayout.BeginHorizontal();
        {
            skills.expCurveConst = EditorGUILayout.FloatField(skills.expCurveConst);
            skills.expCurveScalar = EditorGUILayout.FloatField(skills.expCurveScalar);
            skills.expCurveSquare = EditorGUILayout.FloatField(skills.expCurveSquare);
            skills.expCurveCube = EditorGUILayout.FloatField(skills.expCurveCube);
        }
        EditorGUILayout.EndHorizontal();

        // Display and allow the developer to modify individual skills. //
        showskills = EditorGUILayout.Foldout(showskills, "Show skills");
        if (showskills)
        {
            EditorGUILayout.BeginHorizontal();
             EditorGUILayout.Space();
             EditorGUILayout.LabelField( "Skill Name", "Level" );
             EditorGUILayout.LabelField( "Experience" );
            EditorGUILayout.EndHorizontal();

            for (int i = 0; i < (int)SkillName.MAX_SKILLS; ++i)
            {
                EditorGUILayout.BeginHorizontal();
                 EditorGUILayout.Space(); EditorGUILayout.Space();
                 skills.SetLevel(i, EditorGUILayout.IntField( ((SkillName)i).ToString(), skills.GetLevel(i) ));
                 skills.SetExp(i, EditorGUILayout.IntField( skills.GetExp(i)) );
                EditorGUILayout.EndHorizontal();
            }
        }
    }
}

Even when I modify public variables like maxLevel in the inspector, it always jumps back to default the second it loads.

What the heck is going on here?

Sorry my reply is short (I’m on a tablet)

Try this:

When you change something in the custom inspector, mark the target dirty.

Ha! It worked! Thank you so much!