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:
{
"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.
[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.
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.
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:
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.