Menu
CoddyTech

Zapisz grę

Część sekcji Architektura gier w Unity ścieżki Unity w Coddy. Lekcja 25 z 50.

Stan gry to jeden obiekt zapisany w formacie JSON. Umieść wszystko, czego potrzebuje zapis, w klasie [System.Serializable], wypełnij ją danymi z gry i zapisz jej zawartość z użyciem JsonUtility.ToJson w miejscu, które przetrwa zamknięcie gry. Ten loch zapisuje piętro, złoto i znalezione klucze:

[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 to folder, który Unity udostępnia grze na każdej platformie i który jest zachowywany między uruchomieniami gry oraz podczas aktualizacji. Path.Combine łączy tę ścieżkę z nazwą pliku, używając separatora właściwego dla platformy. File.WriteAllText(path, text) zapisuje plik, zastępując poprzedni, File.Exists informuje, czy plik istnieje, a File.ReadAllText odczytuje go (wszystkie trzy pochodzą z System.IO). Własny folder gry może być tylko do odczytu, dlatego zapisuj dane w persistentDataPath i nigdzie indziej. Utwórz ścieżkę w Awake lub Start: Unity nie pozwala używać persistentDataPath w inicjalizatorze pola.

Klasa zapisu przechowuje tylko to, czego potrzebuje zapis, a gra kopiuje do niej wartości podczas zapisywania i pobiera je z niej podczas wczytywania. Mały zapis można umieścić w PlayerPrefs zamiast w pliku: PlayerPrefs.SetString("dungeon", json) i PlayerPrefs.GetString("dungeon") przechowują ten sam JSON. Zapisuj grę, gdy wydarzy się coś wartego zachowania, w punkcie kontrolnym lub za pomocą przycisku Save: OnApplicationQuit uruchamia się przy normalnym zamknięciu gry, ale telefon może zamknąć grę działającą w tle bez wywołania tej metody.

challenge icon

Wyzwanie

Średni

Odkrywca porusza się po wyspie za pomocą strzałek, a klawisz spacji umieszcza flagę w miejscu, w którym stoi odkrywca. Zapisz stan gry na wyspie w pliku island.json:

  • W pliku IslandSave.cs napisz klasę [System.Serializable] o nazwie IslandSave z publicznymi polami playerPosition (typu Vector3) oraz flags (typu List<Vector3>).
  • Metoda Save(), wywoływana przez przycisk Save, zapisuje pozycję odkrywcy i flagi w formacie JSON do pliku island.json w Application.persistentDataPath.
  • W metodzie Start(), jeśli plik island.json istnieje, przywróć odkrywcę w zapisanym miejscu i ponownie umieść każdą zapisaną flagę za pomocą PlantFlag, aby flagi znalazły się na liście przy następnym zapisie.

Naciśnij Play, umieść kilka flag i kliknij Save, a następnie Stop i ponownie Play. Potem kliknij Check.

Spróbuj swoich sił

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

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

    // Przycisk Save wywołuje tę metodę
    public void Save()
    {
        // Zapisz pozycję gracza i flagi do island.json
    }
}
quiz iconSprawdź się

Ta lekcja zawiera krótki quiz. Zacznij lekcję, żeby na niego odpowiedzieć i śledzić swoje postępy.

Wszystkie lekcje w sekcji Architektura gier w Unity