🎮 UnityDocs

Guardado binario

Cómo guardar datos en binario en vez de JSON: cuándo compensa (partidas grandes, ofuscar), cómo hacerlo con un writer manual, por qué evitar BinaryFormatter (obsoleto e inseguro) y la verdad sobre 'proteger' un guardado local.

📄 ArtículoAvanzado✅ RevisadoUnity 6.0 LTSActualizado 2026-07-17
DificultadConceptual Código Matemáticas
Tiempo📖 Lectura 8 min · ⌨️ Práctica 20 min

¿Binario o JSON?#

El guardado JSON es legible y perfecto para casi todo. El binario guarda bytes crudos: ocupa menos, carga más rápido y no es legible a simple vista. Compensa en partidas grandes (mundos enormes, mucho estado) o cuando quieres que no se lea fácil. Para la mayoría de juegos, JSON sigue ganando por comodidad.

⚖️ Comparativa · JSON vs binario
JSONBinario
Legible / depurableSí (lo abres y lo lees)No
TamañoMayorMenor
VelocidadBuenaMejor en datos grandes
Fácil de editar por el jugadorSí (trampas)Menos (pero no imposible)
Comodidad para el programadorAltaMedia (escribes campo a campo)

El camino recomendado: BinaryWriter/Reader#

Escribes y lees campo a campo. Es explícito pero totalmente bajo tu control:

C#
using System.IO;
using UnityEngine;

public static class GuardadoBinario
{
    static string Ruta => Path.Combine(Application.persistentDataPath, "save.dat");

    public static void Guardar(int nivel, float vida, Vector3 pos)
    {
        using var fs = new FileStream(Ruta, FileMode.Create);
        using var w = new BinaryWriter(fs);
        w.Write(1);            // versión del formato (¡clave para migrar!)
        w.Write(nivel);
        w.Write(vida);
        w.Write(pos.x); w.Write(pos.y); w.Write(pos.z);
    }

    public static void Cargar(out int nivel, out float vida, out Vector3 pos)
    {
        nivel = 0; vida = 100; pos = Vector3.zero;
        if (!File.Exists(Ruta)) return;
        using var fs = new FileStream(Ruta, FileMode.Open);
        using var r = new BinaryReader(fs);
        int version = r.ReadInt32();          // lee la versión primero
        nivel = r.ReadInt32();
        vida = r.ReadSingle();
        pos = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
    }
}
Guarda una versión al principio del archivo

El binario es rígido: si mañana añades un campo, los guardados viejos dejan de cuadrar. Escribe un número de versión como primer valor y, al cargar, decide qué leer según él. Es la diferencia entre poder actualizar el juego y romper todas las partidas guardadas.

No uses BinaryFormatter#

BinaryFormatter está obsoleto y es inseguro

El viejo truco de serializar objetos con BinaryFormatter está deprecado por Microsoft y desaconsejado: es un agujero de seguridad (permite ejecución de código al deserializar datos manipulados) y está siendo retirado de .NET. No lo uses en proyectos nuevos. Usa BinaryWriter/BinaryReader manual, o serializa a JSON y comprime/cifra si hace falta.

La verdad sobre "proteger" el guardado#

Ofuscar o cifrar un guardado local solo frena al jugador casual: quien tenga la clave (y está en tu build) puede revertirlo. No confíes en ello para nada crítico.

  • Para que no se edite fácil: guarda binario o añade un checksum/hash que detecte manipulación.
  • Para datos que no deben falsearse (rankings, economía competitiva): la única vía seria es validarlos en un servidor. Ver cloud save.

Errores frecuentes#

  • Usar BinaryFormatter (obsoleto e inseguro).
  • No escribir una versión: un cambio de formato invalida todos los guardados.
  • Leer los campos en distinto orden del que se escribieron (el binario es posicional: el orden es el contrato).
  • Creer que cifrar el guardado local lo hace "a prueba de trampas" (no lo es).
  • No envolver la carga en manejo de errores para archivos corruptos (ver excepciones).

Ponte a prueba#

📝 Pon a prueba lo aprendido

Resumen#

El guardado binario ocupa menos, carga más rápido y no es legible a simple vista: útil para partidas grandes o para poner difícil la edición. Hazlo con BinaryWriter/BinaryReader campo a campo, escribiendo un número de versión al principio para poder migrar. Evita BinaryFormatter (obsoleto e inseguro). Y ten claro que "proteger" un guardado local solo frena al casual: para datos que no deben falsearse, valídalos en el servidor con cloud save. Para la mayoría de casos, el JSON sigue siendo la opción cómoda.

Fuentes y para profundizar