Saltar al contenido
ReadySpawn

Cómo hacer un sistema de guardado en Unity con JSON

Por Imersa Studios · Actualizado el

Pon todo lo que quieras conservar en una sola clase [Serializable], conviértela a JSON con JsonUtility.ToJson y escríbela en Application.persistentDataPath. Para cargar, lee el archivo y llama a JsonUtility.FromJson. Ese es el núcleo; el resto es decidir qué guardar y cuándo.

1. Pon el estado guardado en una clase

No guardes GameObjects ni MonoBehaviours. Guarda datos simples: números, cadenas, vectores y listas. Una sola clase facilita versionar más adelante.

using UnityEngine;

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

2. Escribe y lee el archivo

Application.persistentDataPath apunta a una carpeta que sobrevive a las actualizaciones en todas las plataformas. Escribe primero en un archivo temporal y luego cámbialo, para que un fallo a mitad de escritura nunca corrompa la partida del jugador.

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. ¿Archivo JSON o PlayerPrefs?

Archivo JSONPlayerPrefs
Mejor paraProgreso del juego, inventarios, mundosAjustes: volumen, calidad, última pestaña del menú
TamañoCualquier tamañoValores pequeños
Inspeccionar y hacer copiaAbre el archivo en cualquier editorOculto en el registro o en un plist
WebGLNecesita sincronizar con IndexedDBFunciona sin más

Una configuración habitual es usar ambos: JSON para el juego, PlayerPrefs para los ajustes. Para guardar JSON en PlayerPrefs, llama a PlayerPrefs.SetString("save", json) y luego a PlayerPrefs.Save().

4. Decide cuándo guardar

  • En eventos: recoger una moneda, llegar a un checkpoint, terminar una misión. El jugador nunca pierde más que un instante.
  • Al salir: OnApplicationQuit y OnApplicationPause(true) en móvil, donde las apps se cierran sin aviso.
  • No en cada frame: escribir a disco es lento. Marca los datos como sucios y guarda una vez al final del frame o con un temporizador.

Conserva el campo version del paso 1. Cuando añadas campos en una actualización, las partidas antiguas siguen cargando: los campos que faltan reciben sus valores por defecto, y puedes migrar según el número de versión.

Sáltate la configuración: un sistema de guardado listo

El Sistema de Guardado y Carga para Unity es este patrón ya terminado: un controlador, una casilla JSON/PlayerPrefs, checkpoints, monedas, plataformas de color y un nivel de demostración, con todo el código C#. Combina bien con el Sistema de Inventario y el Personalizador de Personaje, que guarda atuendos de la misma manera.

Preguntas frecuentes

Quién lo escribió

Imersa Studios crea los sistemas Unity, los packs low poly y las guías que se venden en itch.io. El código y las técnicas de aquí salen de publicar esos productos. Más sobre el estudio.