JSON Serialization In Unity

Last Updated : 4 May, 2026

PlayerPrefs can only save numbers and strings. But what if you need to save a player's inventory, position, health and quest progress, then JSON solves this by converting complex data into text format. JSON (JavaScript Object Notation) is a text format that stores structured data. It looks like this:

C#
{
    "playerName": "Hero",
    "health": 100,
    "position": {"x": 10, "y": 0, "z": 5},
    "inventory": ["Sword", "Shield", "Potion"]
}

JSON is simple, readable, and Unity can convert your C# classes to JSON automatically.

When to Use JSON

  • Saving game state: Stores position, health, and inventory together.
  • Player inventory: Stores a list of items.
  • Quest progress: Stores multiple quests with different states.
  • Character stats: Stores level, XP, skills, and equipment.

JSON is perfect when you need to save many different values as one file.

Step 1: Create a Save Data Class

First, create a class that holds all the data you want to save.

C#
[System.Serializable]
public class GameData
{
    public string playerName;
    public int level;
    public int health;
    public float[] position;  // x, y, z
    public int score;
    public string[] inventory;
}

[System.Serializable] is required. It tells Unity this class can be converted to JSON.

Step 2: Save Data to JSON

Convert your class object into a JSON string and save it.

C#
public class SaveSystem : MonoBehaviour
{
    public void SaveGame(GameData data)
    {
        // Convert to JSON string
        string jsonString = JsonUtility.ToJson(data);
        // Save to PlayerPrefs
        PlayerPrefs.SetString("GameSave", jsonString);
        PlayerPrefs.Save();
        Debug.Log("Game Saved: " + jsonString);
    }
}

JsonUtility.ToJson() converts your class into a JSON string. Then save that string using PlayerPrefs.

Step 3: Load Data from JSON

Retrieve the JSON string and convert it back to your class.

C#
public GameData LoadGame()
{
    // Check if save exists
    if (PlayerPrefs.HasKey("GameSave"))
    {
        // Get JSON string
        string jsonString = PlayerPrefs.GetString("GameSave");
        // Convert back to GameData object
        GameData data = JsonUtility.FromJson<GameData>(jsonString);
        Debug.Log("Game Loaded");
        return data;
    }
    // No save found, return new empty data
    return new GameData();
}

JsonUtility.FromJson<GameData>() converts the JSON string back into a GameData object.

Complete Working Example

Here's a complete save system for a player:

C#
using UnityEngine;
[System.Serializable]
public class PlayerData
{
    public int health;
    public int score;
    public float x, y, z;  // position
    public int ammo;
}
public class GameManager : MonoBehaviour
{
    public PlayerData playerData;
    public Transform player;
    void Start()
    {
        LoadGame();
    }
    void Update()
    {
        // Update data in real time
        playerData.health = GetComponent<Health>().currentHealth;
        playerData.score = GetComponent<Score>().currentScore;
        playerData.x = player.position.x;
        playerData.y = player.position.y;
        playerData.z = player.position.z;
    }
    
    public void SaveGame()
    {
        string json = JsonUtility.ToJson(playerData);
        PlayerPrefs.SetString("PlayerSave", json);
        PlayerPrefs.Save();
        Debug.Log("Saved!");
    }
    
    public void LoadGame()
    {
        if (PlayerPrefs.HasKey("PlayerSave"))
        {
            string json = PlayerPrefs.GetString("PlayerSave");
            playerData = JsonUtility.FromJson<PlayerData>(json);
            // Apply loaded data
            GetComponent<Health>().currentHealth = playerData.health;
            GetComponent<Score>().currentScore = playerData.score;
            player.position = new Vector3(playerData.x, playerData.y, playerData.z);
            
            Debug.Log("Loaded!");
        }
    }
}

JSON vs PlayerPrefs (Direct)

JSON + PlayerPrefs

  • Save multiple values using a single key.
  • Supports complex data (lists, arrays, objects).
  • Easy to read and debug.
  • Cleaner code with one Save/Load system.

PlayerPrefs alone

  • Requires one key per value.
  • Does not support complex data.
  • Harder to read and debug.
  • Leads to many Get/Set lines.
Comment
Article Tags:

Explore