שמירת המשחק
חלק מהיחידה ארכיטקטורת משחקים ב-Unity במסלול ה-Unity של Coddy. שיעור 25 מתוך 50.
משחק שמירה הוא אובייקט אחד שנכתב כ־JSON. שמים את כל מה שהשמירה צריכה במחלקת [System.Serializable], ממלאים אותה מתוך המשחק וכותבים את JsonUtility.ToJson שלה במקום כלשהו שממשיך להתקיים גם אחרי שהמשחק מסתיים. הצינוק הזה שומר את הקומה, את הזהב ואת המפתחות שנמצאו:
[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 היא תיקייה ש־Unity מספקת למשחק בכל פלטפורמה, והיא נשמרת בין משחקים וגם במהלך עדכונים. Path.Combine מחברת אותה ואת שם הקובץ באמצעות המפריד של הפלטפורמה. File.WriteAllText(path, text) כותבת את הקובץ ומחליפה קובץ ישן, File.Exists מציינת אם קיים קובץ, ו־File.ReadAllText קוראת אותו בחזרה (שלושתן מתוך System.IO). ייתכן שתיקיית המשחק עצמה תהיה לקריאה בלבד, לכן שומרים ב־persistentDataPath ולא בשום מקום אחר. בונים את הנתיב ב־Awake או ב־Start: Unity לא מאפשרת להשתמש ב־persistentDataPath באתחול של שדה.
מחלקת השמירה מכילה רק את מה שהשמירה צריכה, והמשחק מעתיק אליה ערכים כדי לשמור, ומעתיק ממנה ערכים כדי לטעון. אפשר לשמור שמירה קטנה ב־PlayerPrefs במקום בקובץ: PlayerPrefs.SetString("dungeon", json) ו־PlayerPrefs.GetString("dungeon") שומרות את אותו JSON. שומרים כשקורה משהו שכדאי לשמור, בנקודת ביקורת או באמצעות כפתור שמירה: OnApplicationQuit פועלת ביציאה רגילה, אבל טלפון יכול לסגור משחק שפועל ברקע בלי להפעיל אותה.
אתגר
בינוניהחוקר הולך באי בעזרת מקשי החצים, ומקש הרווח שותל דגל במקום שבו החוקר עומד. הפוך את האי למשחק שמור בקובץ island.json:
- ב־
IslandSave.cs, כתוב מחלקה[System.Serializable]בשםIslandSaveעם השדות הציבורייםplayerPosition(מסוג Vector3) ו־flags(מסוגList<Vector3>). Save(), שאותו מפעיל כפתור Save, כותבת את מיקום החוקר ואת הדגלים כ־JSON אלisland.jsonב־Application.persistentDataPath.- ב־
Start(), אםisland.jsonקיים, החזר את החוקר למיקום השמור ושתול שוב כל דגל שמור, באמצעותPlantFlag, כך שהדגלים יהיו ברשימה לקראת השמירה הבאה.
לחץ על Play, שתול כמה דגלים ולחץ על Save, ואז לחץ על Stop ועל Play שוב. לאחר מכן לחץ על Check.
נסו בעצמכם
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");
// טען כאן את 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);
}
// הכפתור Save קורא לזה
public void Save()
{
// כתוב את מיקום השחקן ואת הדגלים ל-island.json
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.