التحميل والقيم الافتراضية
جزء من قسم هندسة الألعاب في Unity في رحلة Unity على Coddy. الدرس 32 من 64.
يجب أن يتعامل التحميل مع ملفات الحفظ غير الموجودة أو غير المكتملة. تحفظ لعبة سباق بيانات من نوع 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 بأمان للاعبين الجدد وملفات الحفظ القديمة.
- في
Start()، استبدل سطر FromJson بـif (File.Exists(path))وكتلةelse. - إذا وُجد الملف، املأ pet في Inspector:
JsonUtility.FromJsonOverwrite(File.ReadAllText(path), pet);، ثم سجّلWelcome back, Mochiمنpet.petName. - إذا لم يوجد، فسجّل
A new pet: Biscuitبالطريقة نفسها.
اضغط «العب»، وأطعم الحيوان الأليف، ثم أوقف اللعبة واضغط «العب»: ستظهر رسالة الترحيب بعودته. ثم اضغط «تحقق».
جرّب بنفسك
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;
}
}
جميع دروس هندسة الألعاب في Unity
1المكوّنات، لا التسلسلات الهرمية
مكوّنات صغيرةنص برمجي أساسي للعدومكوّنات مجرّدةالمكوّنات تعمل معًامراجعة: برج معياريمراجعة: مدفع مزدوج4البيانات المُسلسلة
الأصناف القابلة للتسلسلالقوائم في Inspectorالتعدادات في Inspectorمراجعة: جدول الغنائممراجعة: اختيار الغنائم عشوائيًا2الواجهات في Unity
IDamageableالواجهات وTryGetComponentGetComponentsمراجعة: مفتاح التفاعلمراجعة: أقرب عنصر ضمن النطاق3الأحداث
الأحداث في C# ضمن Unityالاشتراك في OnEnableحقول UnityEventالأحداث تحرّك واجهة المستخدممراجعة: نافذة الإنجاز المنبثقةمراجعة: مؤقّت النافذة المنبثقة6الحفظ باستخدام JSON
JsonUtilityاحفظ اللعبةالتحميل والقيم الافتراضيةمراجعة: خانات الحفظاختر خانة واحذفهاتدرّب بنفسك: Playground لـ Unity