Menu
CoddyTech

Guarda la partida

Parte de la sección Arquitectura de juegos en Unity del Journey de Unity de Coddy. Lección 31 de 64.

Una partida guardada es un objeto escrito como JSON. Pon todo lo que necesite la partida en una clase [System.Serializable], rellénala con los datos del juego y escribe su contenido con JsonUtility.ToJson en algún lugar que persista cuando termine la partida. Esta mazmorra guarda el piso, el oro y las llaves encontradas:

[System.Serializable]
public class DungeonSave
{
    public int floor;
    public int gold;
    public List<string> keys;
}
using System.Collections.Generic;
using System.IO;
using UnityEngine;

public class Dungeon : MonoBehaviour
{
    public int floor = 1;
    public int gold;
    public List<string> keys = new List<string>();
    private string path;

    void Start()
    {
        path = Path.Combine(Application.persistentDataPath, "dungeon.json");
        if (File.Exists(path))
        {
            DungeonSave save = JsonUtility.FromJson<DungeonSave>(File.ReadAllText(path));
            floor = save.floor;
            gold = save.gold;
            keys = save.keys;
        }
    }

    public void Save()
    {
        DungeonSave save = new DungeonSave();
        save.floor = floor;
        save.gold = gold;
        save.keys = keys;
        File.WriteAllText(path, JsonUtility.ToJson(save));
    }
}

Application.persistentDataPath es una carpeta que Unity proporciona al juego en todas las plataformas y que se conserva entre partidas y durante las actualizaciones. Path.Combine une esa ruta con un nombre de archivo usando el separador de la plataforma. File.WriteAllText(path, text) escribe el archivo y reemplaza uno anterior, File.Exists indica si existe uno y File.ReadAllText lo vuelve a leer (los tres pertenecen a System.IO). Es posible que la carpeta del propio juego sea de solo lectura, así que guarda en persistentDataPath y en ningún otro lugar. Construye la ruta en Awake o Start: Unity no permite usar persistentDataPath en un inicializador de campo.

La clase de guardado solo contiene lo que necesita la partida, y el juego copia los valores en ella para guardar y los extrae de ella para cargar. Un guardado pequeño puede almacenarse en PlayerPrefs en lugar de en un archivo: PlayerPrefs.SetString("dungeon", json) y PlayerPrefs.GetString("dungeon") guardan el mismo JSON. Guarda cuando ocurra algo que valga la pena conservar, al llegar a un punto de control o al pulsar un botón para guardar: OnApplicationQuit se ejecuta al salir normalmente, pero un teléfono puede cerrar un juego en segundo plano sin ejecutar ese método.

challenge icon

Desafío

Intermedio

Guarda la isla en island.json.

  1. En IslandSave.cs, escribe una clase [System.Serializable] llamada IslandSave con public Vector3 playerPosition; y public List<Vector3> flags;.
  2. En Start(), establece path en Path.Combine(Application.persistentDataPath, "island.json").
  3. Save() escribe un IslandSave con transform.position y flags en path como JSON.
  4. Start() vuelve a leer un archivo existente: la posición y llama a PlantFlag para cada bandera.

Pulsa «Jugar», planta banderas, pulsa «Guardar», detén el juego y pulsa «Jugar»: las banderas vuelven a aparecer. Después, pulsa «Comprobar».

Pruébalo tú mismo

using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.InputSystem;

public class Explorer : MonoBehaviour
{
    public GameObject flagPrefab;
    public float speed = 4f;
    private List<Vector3> flags = new List<Vector3>();
    private InputAction moveAction;

    void Start()
    {
        moveAction = InputSystem.actions.FindAction("Move");
        // Carga island.json aquí
    }

    void Update()
    {
        Vector2 input = moveAction.ReadValue<Vector2>();
        transform.Translate(new Vector3(input.x, 0f, input.y) * speed * Time.deltaTime);
        if (Keyboard.current.spaceKey.wasPressedThisFrame)
        {
            PlantFlag(transform.position);
        }
    }

    void PlantFlag(Vector3 position)
    {
        flags.Add(position);
        Instantiate(flagPrefab, new Vector3(position.x, 0.5f, position.z), Quaternion.identity);
    }

    // El botón Save llama a este método
    public void Save()
    {
        // Escribe la posición del jugador y las banderas en island.json
    }
}

Todas las lecciones de Arquitectura de juegos en Unity

Practica por tu cuenta: Playground de Unity