Skip to content
ReadySpawn

How to Make a Save System in Unity with JSON

By Imersa Studios · Updated

Put everything you want to keep in one [Serializable] class, turn it into JSON with JsonUtility.ToJson, and write it to Application.persistentDataPath. To load, read the file and call JsonUtility.FromJson. That's the whole core; the rest is deciding what to save and when.

1. Put the saved state in one class

Don't save GameObjects or MonoBehaviours. Save plain data: numbers, strings, vectors and lists. One class keeps it easy to version later.

using UnityEngine;

[System.Serializable]
public class SaveData
{
    public int version = 1;
    public int coins;
    public Vector3 checkpoint;
    public Color playerColor = Color.white;
}

2. Write and read the file

Application.persistentDataPath points to a folder that survives updates on every platform. Write to a temporary file first and then swap it in, so a crash mid-write never corrupts the player's save.

using System.IO;
using UnityEngine;

public static class SaveSystem
{
    static string FilePath => Path.Combine(Application.persistentDataPath, "save.json");

    public static void Save(SaveData data)
    {
        string tmp = FilePath + ".tmp";
        File.WriteAllText(tmp, JsonUtility.ToJson(data, true));
        if (File.Exists(FilePath)) File.Replace(tmp, FilePath, null);
        else File.Move(tmp, FilePath);
    }

    public static SaveData Load()
    {
        if (!File.Exists(FilePath)) return new SaveData();
        return JsonUtility.FromJson<SaveData>(File.ReadAllText(FilePath));
    }

    public static void Delete()
    {
        if (File.Exists(FilePath)) File.Delete(FilePath);
    }
}

3. JSON file or PlayerPrefs?

JSON filePlayerPrefs
Best forGame progress, inventories, worldsSettings: volume, quality, last menu tab
SizeAny sizeSmall values
Inspect and back upOpen the file in any editorHidden in the registry or a plist
WebGLNeeds IndexedDB syncWorks out of the box

A common setup is both: JSON for the game, PlayerPrefs for settings. To store JSON in PlayerPrefs instead, call PlayerPrefs.SetString("save", json) and then PlayerPrefs.Save().

4. Decide when to save

  • On events: picking up a coin, reaching a checkpoint, finishing a quest. Players never lose more than a moment.
  • On quit: OnApplicationQuit, and OnApplicationPause(true) on mobile, where apps get killed without warning.
  • Not every frame: disk writes are slow. Mark the data dirty and save once at the end of the frame or on a timer.

Keep the version field from step 1. When you add fields in an update, old saves still load: missing fields get their default values, and you can migrate based on the version number.

Skip the setup: a ready save system

The Save & Load System for Unity is this pattern finished: one controller, a JSON/PlayerPrefs checkbox, checkpoints, coins, colour platforms and a demo level, with full C# source. It pairs well with the Inventory System and the Character Customizer, which saves outfits the same way.

Questions

Who wrote this

Imersa Studios builds the Unity systems, low poly packs and field guides sold on itch.io. The code and techniques here come from shipping those products. More about the studio.