שמירת המשחק
חלק מהיחידה ארכיטקטורת משחקים ב-Unity במסלול ה-Unity של Coddy. שיעור 31 מתוך 64.
שמירת משחק היא אובייקט אחד שנכתב בפורמט 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. כדאי לשמור כשקורה משהו ששווה לשמור, בנקודת ביקורת או באמצעות כפתור Save: OnApplicationQuit מופעל כשיוצאים מהמשחק בדרך הרגילה, אבל טלפון יכול לסגור משחק שפועל ברקע בלי להפעיל אותו.
אתגר
בינונישמור את האי בקובץ island.json.
- ב־
IslandSave.cs, כתוב מחלקה[System.Serializable]בשםIslandSaveעםpublic Vector3 playerPosition;ו־public List<Vector3> flags;. - ב־
Start(), הגדר אתpathלערךPath.Combine(Application.persistentDataPath, "island.json"). Save()כותבת אלpathנתוני IslandSave שלtransform.positionו־flagsבפורמט JSON.Start()קוראת בחזרה קובץ קיים: את המיקום, ומפעילה אתPlantFlagעבור כל דגל.
לחץ על "שחק", שתול דגלים, לחץ על Save, עצור ולחץ על "שחק": הם חזרו. ואז לחץ על "בדיקה".
נסו בעצמכם
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
}
}
כל השיעורים ביחידה ארכיטקטורת משחקים ב-Unity
1רכיבים, לא היררכיות
רכיבים קטניםסקריפט בסיסי לאויברכיבים מופשטיםרכיבים שפועלים יחדחזרה: צריח מודולריחזרה: תותח כפול4נתונים שעברו סריאליזציה
מחלקות שניתנות לסריאליזציהרשימות ב־Inspectorטיפוסי Enum ב־Inspectorחזרה: טבלת שללהגרלת השלל2ממשקים ב-Unity
IDamageableממשקים ו-TryGetComponentGetComponentsסיכום: מקש אינטראקציהסיכום: הקרוב ביותר בטווחתרגלו בעצמכם: Unity אונליין