The short version

A ScriptableObject is a Unity object that holds data and lives as an asset file in your project, rather than on a GameObject in a scene. You create, name and edit it in the inspector like any other asset.

It suits player stats, game settings, an inventory definition or a difficulty curve: data authored in the editor and read from anywhere in your game.

vs. MonoBehaviour

A MonoBehaviour is a script attached to a GameObject. A ScriptableObject is its counterpart for pure data.

  • MonoBehaviour lives on a GameObject, inside a scene or prefab. It has Update, Start, a transform, and so on.
  • ScriptableObject lives as a standalone .asset file in your Project window. No GameObject, no scene, no per-frame loop. Just fields.

A ScriptableObject is a single shared asset: every script referencing it reads the same data, with no copies to keep in sync.

Making one

Three steps, all standard Unity:

  1. Write a class that inherits ScriptableObject.
  2. Add [CreateAssetMenu] so it shows up in the Create menu.
  3. Right-click in the Project window and create an instance. Its fields appear in the inspector, ready to edit.
using UnityEngine;

[CreateAssetMenu(menuName = "Player Data")]
public class PlayerData : ScriptableObject
{
    public int gold;
    public int level = 1;
}

That is a plain ScriptableObject. The Persistent Asset example is identical, apart from the base class it inherits.

The catch

A ScriptableObject authors data, but it does not save it. In a built game, a change made while playing lives in memory only and is gone when the game closes: the authored values load fresh on every launch.

In the editor, changes can look like they persist, because Unity writes runtime edits back into the asset on disk. That does not happen in a build.

Persistent Asset adds the missing piece: inherit PersistentScriptableObject instead of ScriptableObject, and the data is saved and restored between sessions.