Unity ScriptableObjects Save Load System: Easy Game Save
Read this article in clean Markdown format for LLMs and AI context.Tired of losing progress when your Unity game crashes or you quit?
Implement a Unity ScriptableObjects Save Load System to reliably persist player data with just a few lines of code.
How the Unity ScriptableObjects Save Load System Works
The core idea is to store your game state in a ScriptableObject asset, then serialize that asset to JSON when you need to save and deserialize it when you load. This eliminates the brittle string‑key mess of PlayerPrefs and lets you add new fields without touching the save/load logic.
Creating the Data Container
First, define a simple C# class that inherits from ScriptableObject. Add fields for everything you want to persist—health, level, inventory, settings, etc.
using UnityEngine;
using System.Collections.Generic;
[CreateAssetMenu(fileName = "GameData", menuName = "SaveSystem/GameData")]
public class GameData : ScriptableObject
{
public int playerHealth = 100;
public int currentLevel = 1;
public List<string> inventory = new List<string>();
// Add more fields as needed
}
Saving to Disk
Next, write a static helper that converts the GameData instance to JSON and writes it to Application.persistentDataPath.
using System.IO;
using UnityEngine;
public static class SaveLoadManager
{
private const string SaveFileName = "gamedata.json";
public static void SaveGame(GameData data)
{
string json = JsonUtility.ToJson(data, true);
string path = Path.Combine(Application.persistentDataPath, SaveFileName);
File.WriteAllText(path, json);
Debug.Log($"Game saved to {path}");
}
public static GameData LoadGame()
{
string path = Path.Combine(Application.persistentDataPath, SaveFileName);
if (!File.Exists(path))
{
Debug.LogWarning("Save file not found. Returning fresh data.");
return CreateInstance<GameData>();
}
string json = File.ReadAllText(path);
GameData data = JsonUtility.FromJson<GameData>(json);
Debug.Log($"Game loaded from {path}");
return data;
}
}
Hooking It Up in Your Scene
- Create a GameData asset via
Assets > Create > SaveSystem > GameData. - Drag the asset onto a manager GameObject in your scene.
- At runtime, fill the asset with current values (e.g., from your player controller).
- Call
SaveLoadManager.SaveGame(yourDataAsset)on pause, exit, or autosave triggers. - Call
SaveLoadManager.LoadGame()inStart()orAwake()to restore state.
Because the data lives in an asset, you avoid the fragile string‑key approach of PlayerPrefs. Adding a new field—say, public bool hasKey—requires no changes to the save/load methods; Unity’s JSON serializer handles it automatically.
Benefits Over PlayerPrefs
- Scalability: Complex nested objects (lists, custom classes) serialize cleanly.
- Safety: No risk of mismatched keys when you rename variables.
- Extensibility: New save versions work out‑of‑the‑box; old files still load, missing fields get default values.
- Debugging: You can inspect the saved JSON file directly in
Application.persistentDataPath.
Quick Checklist for Implementation
- [ ] Create a
ScriptableObjectsubclass with all saveable fields. - [ ] Add
[CreateAssetMenu]for easy asset creation. - [ ] Implement
SaveGameandLoadGameusingJsonUtility. - [ ] Wire the asset to a persistent manager in your scene.
- [ ] Call save on appropriate events (pause, exit, level complete).
- [ ] Call load on game start to restore player progress.
By following these steps, you’ll have a robust Unity ScriptableObjects Save Load System that scales with your game’s complexity and saves you countless hours of debugging. Give it a try and watch your development workflow smooth out instantly.
- →
- →
- →
- →
- →