טעינה וערכי ברירת מחדל
חלק מהיחידה ארכיטקטורת משחקים ב-Unity במסלול ה-Unity של Coddy. שיעור 26 מתוך 50.
הטעינה צריכה להתמודד עם קובצי שמירה שאינם קיימים או שאינם שלמים. משחק מרוצים שומר RaceSave; בגרסה 2 של המשחק נוסף musicVolume:
[System.Serializable]
public class RaceSave
{
public int trophies;
public string car = "Rookie Kart";
public float musicVolume = 0.8f;
}RaceSave save;
if (File.Exists(path))
{
save = JsonUtility.FromJson<RaceSave>(File.ReadAllText(path));
}
else
{
save = new RaceSave();
}לשחקן חדש אין קובץ, וקריאה ל-File.ReadAllText בקובץ חסר זורקת FileNotFoundException, לכן בדקו קודם את File.Exists והתחילו מ-new RaceSave(): 0 גביעים, Rookie Kart ועוצמת קול 0.8 — הערכים הראשוניים של השדות. קובץ של שחקן ותיק מגרסה 1 מכיל {"trophies":3,"car":"Red Racer"}. FromJson יוצר RaceSave חדש, שמפעיל את הערכים הראשוניים של השדות, ואז מגדיר רק את המפתחות שקיימים ב-JSON, ולכן הערך של musicVolume הוא 0.8. מפתח שאין לו שדה במחלקה מתעלמים ממנו. לכן גרסה חדשה של המשחק יכולה לקרוא קובצי שמירה ישנים, כל עוד לכל שדה חדש יש ערך ראשוני הגיוני.
JsonUtility.FromJsonOverwrite(json, obj) ממלא אובייקט שכבר קיים במקום ליצור אובייקט חדש, ומשאיר כל שדה שאינו מופיע ב-JSON כפי שהיה. FromJson לא יכול ליצור MonoBehaviour או ScriptableObject (Unity זורקת Cannot deserialize JSON to new instances of type 'RaceSettings.'), לכן טוענים נכס הגדרות באמצעות דריסת תוכנו: JsonUtility.FromJsonOverwrite(json, settings);. דריסת התוכן גם משמרת את הערכים שכבר קיימים באובייקט, כמו אלה שה-Inspector העניק לו, בעוד FromJson היה מחזיר את הערכים הראשוניים של המחלקה.
אתגר
בינוניחיית המחמד הווירטואלית טוענת את pet.json כשהמשחק מתחיל, ולחיצה על מקש הרווח מאכילה את חיית המחמד ושומרת אותה. הטעינה נכשלת בשתי דרכים:
- לשחקן חדש אין
pet.json, והמתודה Start נעצרת עם FileNotFoundException. כשאין קובץ, יש להשאיר את חיית המחמד כפי שהוגדרה ב-Inspector (Biscuit, hunger 30, happiness 80, Ball) ולתעד ביומןA new pet: Biscuit. - גרסה 1 של המשחק שמרה רק את
petNameואתhunger;happinessו-toysנוספו בגרסה 2 (ראו PetSave.cs). כששומרים ישנים נטענים באמצעות FromJson, הם מקבלים את הערך 50 של המחלקה וללא צעצועים, ולא את הערכים של Inspector. טענו קובץ קיים אלpetבאמצעותJsonUtility.FromJsonOverwrite, כך שכל מה שחסר בקובץ ישמור על הערך שהוגדר ב-Inspector, ותעדו ביומן ברכת ברוכים השבים עם השם שנטען, למשלWelcome back, Mochi.
לחצו על Play והאכילו את חיית המחמד, לאחר מכן לחצו על Stop ועל Play שוב, ואז לחצו על Check.
נסו בעצמכם
using System.IO;
using UnityEngine;
using UnityEngine.InputSystem;
using TMPro;
public class PetCare : MonoBehaviour
{
public PetSave pet;
public TMP_Text petText;
private string path;
void Start()
{
path = Path.Combine(Application.persistentDataPath, "pet.json");
pet = JsonUtility.FromJson<PetSave>(File.ReadAllText(path));
Show();
}
void Update()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
pet.hunger = Mathf.Max(pet.hunger - 10, 0);
pet.happiness = Mathf.Min(pet.happiness + 5, 100);
File.WriteAllText(path, JsonUtility.ToJson(pet));
Show();
}
}
void Show()
{
petText.text = pet.petName + ": hunger " + pet.hunger + ", happiness " + pet.happiness;
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.