Quick answer: Inspector array values revert because code re-initializes them in Awake/Start, the field lacks [SerializeField], or a prefab override is being applied. Stop overwriting the array in initialization methods, ensure the attribute is present, and apply prefab overrides correctly. For persistent data, use a ScriptableObject.

Here is how to fix Unity SerializedField arrays resetting on play. You carefully populate an array in the Inspector — waypoints, spawn points, item references. You press Play. The array is empty or back to its default values. Exit Play mode and the values are there again. This back-and-forth drives developers to question their sanity, but the cause is almost always one of four things.

The Symptom

An array or list field displayed in the Inspector loses its values when entering Play mode. Variants include:

The values are visible in the Inspector in Edit mode but gone at runtime.

Cause 1: Code Overwrites the Array

The most common cause. Your script re-assigns the array in Awake, Start, or OnEnable:

public class WaypointManager : MonoBehaviour
{
    [SerializeField] private Transform[] waypoints;

    void Awake()
    {
        waypoints = new Transform[0]; // THIS DESTROYS YOUR INSPECTOR VALUES
    }
}

Unity deserializes the Inspector values into the field before Awake runs. Then Awake overwrites them with an empty array. Remove the re-assignment. If you need a fallback, check for null first:

void Awake()
{
    if (waypoints == null || waypoints.Length == 0)
    {
        waypoints = FindDefaultWaypoints(); // only if Inspector is empty
    }
}

Cause 2: Missing SerializeField Attribute

Private fields need [SerializeField] to be saved by Unity. Without it, the field appears in a custom editor or debug Inspector but Unity does not serialize it — so the value is lost on domain reload.

// WRONG: private without attribute, not serialized
private int[] scores;

// RIGHT: private with attribute, serialized
[SerializeField] private int[] scores;

// ALSO RIGHT: public fields are serialized by default
public int[] scores;

Note that public fields are serialized automatically. [SerializeField] is only needed for private or protected fields.

Cause 3: Prefab Override Reverts Values

If your object is a prefab instance and the array was modified only on the instance without applying the override, Unity may revert it. This happens when:

Fix: right-click the field in the Inspector and select “Apply to Prefab”. Or modify the prefab asset directly by opening it in Prefab Mode.

Cause 4: Domain Reload Disabled

With Enter Play Mode Options enabled and Reload Domain unchecked (Project Settings > Editor), static fields and field initializers are not reset between Play sessions. This causes the opposite problem: arrays keep stale runtime data after exiting Play mode.

public class EnemyRegistry : MonoBehaviour
{
    private static List<Enemy> allEnemies = new List<Enemy>();

    // With Domain Reload off, this list keeps growing across play sessions

    [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)]
    static void ResetStatics()
    {
        allEnemies = new List<Enemy>(); // manually reset
    }
}

Use [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.SubsystemRegistration)] to reset static state when Domain Reload is off. This runs early enough to clear stale data before your game initializes.

ScriptableObject Persistence

For data that genuinely needs to survive Play mode transitions, use a ScriptableObject:

[CreateAssetMenu(fileName = "SpawnData", menuName = "Game/Spawn Data")]
public class SpawnData : ScriptableObject
{
    public Vector3[] spawnPoints;
    public int[] enemyCounts;
}

public class SpawnManager : MonoBehaviour
{
    [SerializeField] private SpawnData data; // reference the asset

    void Start()
    {
        foreach (Vector3 point in data.spawnPoints)
        {
            SpawnEnemies(point);
        }
    }
}

ScriptableObject assets persist their data in the .asset file. Changes made in the Inspector stick. Be aware that changes made during Play mode to ScriptableObject fields do persist after exiting Play mode, unlike MonoBehaviour component data.

Debugging Serialization

Switch the Inspector to Debug mode (click the three-dot menu in the Inspector header). This shows all serialized fields with their raw values, including arrays. If your field does not appear in Debug mode, it is not being serialized. Check the attribute and field type.

Also check the console for serialization warnings. Unity logs messages like “Field ‘scores’ is not serializable” if the element type cannot be serialized (interfaces, abstract classes without the [SerializeReference] attribute, dictionaries).

“The Inspector shows what Unity saved. If the value disappears on Play, something between deserialization and your first frame is overwriting it. Find that line.”

Related Issues

For ScriptableObject data disappearing at build time, check that assets are included in a Resources folder or referenced by a scene. For prefab override conflicts in teams, see Unity’s Prefab Variant documentation. For serialization of custom classes, ensure they have the [System.Serializable] attribute.

Check Awake/Start for overwrites. Add [SerializeField]. Apply prefab overrides. Use ScriptableObject for persistent data.