السلام عليكم, في هذا الدرس اردت مناقشة فكرة هذا الطريقة في حفظ الملفات النقاط و هذا الامر يقتصر على الناقط فقط بل على اي شيء تقريباً, جميعنا نستخدم الفئة PlayerPrefs في حفظ النقاط و لكن هنا سنناقش استخدام فئات مثل BinaryFormatter و FileStream, و سنتعرف على طريقة الوصول الى ملف الحفظ الذي ينشئ تلقائياً و بنفس الاسم الذي حددته.
نظام Binary لحفظ الملفات يتميز بكونه يقوم بأنشاء ملفات قابلة للقراءة فقط بعكس نظام xml الذي ينشئ ملفات قابلة للقراءة و الكتابة, بحيث ينشئ ملف من نوع Binary وهو مشفر لأنه قابل للقراءة فقط و هذا النظام يستخدم كثيراً في الالعاب و لكن كلاً حسب استخدامه له.
للوصول الى الفئات الخاصة بهذا النظام يجب علينا الوصول اولاً الى نطاق الاسم Binary ايضاً الفئة FileStream علينا الوصول الى نطاق الاسم IO ويمتد من System, اذن العملية الاولى هي الوصول الى انطقه الاسم المذكورة.
أنشئ ملف برمجي باسم SaveData و اضف الامتدادات الاتية:
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
الان في الملف البرمجي يجب علينا تعرف فئة اخرى وهي جزء منه و عبر نطاق الاسم System نستطيع الوصول الى الفئة Serializable, اضف الكود التالي و يجب ان يكون خارج اي فئة:
[Serializable]
class PlayerData{
public int score;
}
هذا المتغير هو وسيط لحفظ النقاط و استعادتها و هذه الفئة ستكون متاحة للتسلسل.
في نفس الملف البرمجي خارج الفئة الحالية عرف متغير يمثل النقاط مثل الموجود في الفئة PlayerData.
الان في نفس الملف عرف دالتين الاولى باسم Save و الثانية باسم Load و كلاً حسب وضيفته و يجب ان يكونان public لنستطيع اضافتهم الى الازرار لاحقاً.
في الدالة Save اضف الكود التالي:
public void Save()
{
BinaryFormatter bin = new BinaryFormatter();
FileStream file = File.Create(Application.persistentDataPath + "/playerInfo.data");
PlayerData p_data = new PlayerData();
p_data.score = Score;
bin.Serialize(file,p_data);
file.Close();
}
حسناً دعنا نناقش الامر.
في البداية عرفت متغير يمثل الفئة BinaryFormatter, ايضاً في السطر اسفلة عرفت متغير يمثل الفئة FileStream و من خلال الفئة File استطعت الوصول الى الدالة Create وهي تطلب متغير يحدد مسار البيانات التي ستنشئها لكي تستطيع استعادتها لاحقاً و كما تلاحظ عرفت مسار و اعطيته اسم.
السرط اسفلة عرفت متغير يمثل الفئة PlayerData للوصول الى المتغير score, و في السطر اسفلة تلاحظ ان المتغير score من الفئة PlayerData سيخزن قيمة المتغير Score الموجود في الملف SaveData, بحيث اننا سنخزن القيمة في المتغير score.
من المتغير bin نصل الى الدالة Serialize وهي تطلب مسار التسلسل و الكائن الذي نريد عمل تسلسل بيانات له و بكل بساطة اضف المتغيرين كما تلاحظ واخيراً اغلقت الملف.
الدالة Load لن تختلف كثيراً على الدالة Save, فوظيفتها هي التحقق من ان الامتداد و الاسم موجودين و من ثم استخراج البيانات ووضعها في المتغير score من الفئة PlayerData بحيث ان المتغير Score يأخذ القيمة المخزنة, اضف الكود التالي لنناقشه اكثر.
public void Load()
{
if(File.Exists(Application.persistentDataPath + "/playerInfo.data"))
{
BinaryFormatter bin = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/playerInfo.data",FileMode.Open);
PlayerData p_data = (PlayerData)bin.Deserialize(file);
file.Close();
Score = p_data.score;
}
}
اولاً الشرط سيتحقق لنا من الامتداد وهل هو موجود ام لا؟
ففي حالة تحقق الشرط تجد انني عرفت نفس المتغير السابقة التي تمثل الفئات و لكن في المتغير file تلاحظ استخدامي للدالة Open و ستقوم بفتح ملف المحفوظ و يجب علينا تحديد نوع الفتح و تلاحظ في نهاية السطر ان نوعه هو Open و سيقوم بفتح الملف تلقائياً.
المتغير p_data سيقوم بإلغاء تسلسل البيانات لكي سيتعيدها, فالدالة Deserialize تطلب متغير يمثل الملف المتسلسل و بما انه file فسنقوم بوضعه.
اخيراً اغلفت الملف و جعلت المتغير Score يأخد القيمة التي خزنها المتغير score من الفئة PlayerData.
بهذا الشكل نكون قد هيئنا النظام للاستخدام فبالعودة الى المشروع عليك انشاء زرين الاول لحفظ البيانات و الاخر لاستعادتها, لاحظ الصورة:
الان كل زر سيأخذ الدالة التي تمثله و حال تشغيل اللعبة و قمت برفع قيمة النقاط و عمل حفظ لها ستجد انه تم انشاء ملف باسم playerInfo.data و غالباً يكون امتداداه هو:
C:\Users\NameUser\AppData\LocalLow\DefaultCompany\NameProject
قم بتغيير NameUser الى اسم المستخدم, ايضاً NameProject الى اسم المشروع و ستجد الملف مع امتداداه .data
اخيراً في حالة عدت الى اللعبة و عملت Load ستجد انه قد تمت استعادة القيم المحفوظة بنجاح.
و بهذا الشكل نكون قد انهينا شرح هذا النظام و اتمنى ان تستفيدوا, و اي استفسار او سؤال تفضلوا وشكراً على مروركم.
الملف البرمجي كامل:
using UnityEngine;
using System.Collections;
using System;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
public class SaveData : MonoBehaviour {
public int Score;
public void Save()
{
BinaryFormatter bin = new BinaryFormatter();
FileStream file = File.Create(Application.persistentDataPath + "/playerInfo.data");
PlayerData p_data = new PlayerData();
p_data.score = Score;
bin.Serialize(file,p_data);
file.Close();
}
public void Load()
{
if(File.Exists(Application.persistentDataPath + "/playerInfo.data"))
{
BinaryFormatter bin = new BinaryFormatter();
FileStream file = File.Open(Application.persistentDataPath + "/playerInfo.data",FileMode.Open);
PlayerData p_data = (PlayerData)bin.Deserialize(file);
file.Close();
Score = p_data.score;
}
}
}
[Serializable]
class PlayerData{
public int score;
}