Menu
CoddyTech

Sauvegarder la partie

Fait partie de la section Architecture de jeu dans Unity du Journey Unity de Coddy. Leçon 31 sur 64.

Une sauvegarde est un objet écrit au format JSON. Place tout ce dont la sauvegarde a besoin dans une classe [System.Serializable], remplis-la à partir du jeu et écris le résultat de JsonUtility.ToJson quelque part où il persistera après la fermeture du jeu. Ce donjon conserve l’étage, l’or et les clés trouvées :

[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 est un dossier que Unity fournit au jeu sur chaque plateforme et qui est conservé entre les parties et lors des mises à jour. Path.Combine le combine avec un nom de fichier en utilisant le séparateur de la plateforme. File.WriteAllText(path, text) écrit le fichier en remplaçant l’ancien, File.Exists indique si le fichier existe et File.ReadAllText le lit (ces trois méthodes viennent de System.IO). Le dossier du jeu lui-même peut être en lecture seule ; les sauvegardes doivent donc être placées dans persistentDataPath, et nulle part ailleurs. Construis le chemin dans Awake ou Start : Unity n’accepte pas persistentDataPath dans l’initialiseur d’un champ.

La classe de sauvegarde contient uniquement ce dont la sauvegarde a besoin, et le jeu y copie les valeurs pour enregistrer, puis les récupère pour charger. Une petite sauvegarde peut être stockée dans PlayerPrefs plutôt que dans un fichier : PlayerPrefs.SetString("dungeon", json) et PlayerPrefs.GetString("dungeon") contiennent le même JSON. Enregistre quand un événement mérite d’être conservé, à un point de contrôle ou avec un bouton Save : OnApplicationQuit s’exécute lors d’une fermeture normale, mais un téléphone peut fermer un jeu en arrière-plan sans appeler cette méthode.

challenge icon

Défi

Moyen

Enregistre l’île dans island.json.

  1. Dans IslandSave.cs, écris une classe [System.Serializable] IslandSave avec public Vector3 playerPosition; et public List<Vector3> flags;.
  2. Dans Start(), définis path sur Path.Combine(Application.persistentDataPath, "island.json").
  3. Save() écrit un objet IslandSave contenant transform.position et flags dans path au format JSON.
  4. Start() lit le fichier existant : la position, puis appelle PlantFlag pour chaque drapeau.

Appuie sur « Jouer », plante des drapeaux, appuie sur Save, arrête puis appuie sur « Jouer » : ils sont de retour. Ensuite, appuie sur « Vérifier ».

Essayez vous-même

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");
        // Charge island.json ici
    }

    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);
    }

    // Le bouton Save appelle cette méthode
    public void Save()
    {
        // Écris la position du joueur et les drapeaux dans island.json
    }
}

Toutes les leçons de Architecture de jeu dans Unity

Entraînez-vous par vous-même : Playground Unity