كيفية حفظ وتحميل التقدم الخاص بك اللاعبين في الوحدة
Arabic (العربية/عربي) translation by Aisy Abdullah (you can also view the original English article)



في هذا البرنامج التعليمي، سوف تتعلم كيفية تنفيذ نظام بسيط لإنشاء وإدارة savegames للألعاب الوحدة الخاصة بك. وسوف نبني إطارا لنهائي قائمة رئيسية مثل الخيال التي تمكن اللاعبين إنشاء جديدة وفريدة من نوعها حفظ الملفات، وتحميل تلك القائمة. مبادئ أثبتت تسمح لك لتوسيعها لتشمل احتياجات أيا كانت اللعبة الخاصة بك.
بنهاية البرنامج التعليمي، كنت قد تعلمت كيفية:
- حفظ وتحميل بيانات اللعبة في Unity3D باستخدام التسلسل
- استخدام المتغيرات ثابتة للاستمرار البيانات عبر تغييرات المشهد
ملاحظة: هذا النهج لحفظ وتحميل بيانات اللعبة يعمل على كافة الأنظمة الأساسية باستثناء لاعب ويب. للحصول على مزيد من المعلومات حول حفظ بيانات اللعبة في 'مشغل الشبكة'، نلقي نظرة على مستندات رسمية على لاعب الوحدة على شبكة الإنترنت والاتصالات المستعرض.
دعنا المسلسل
هو أول شيء نحن ذاهبون للقيام بإنشاء بعض التعليمات البرمجية التي تسمح لنا بإجراء تسلسل البيانات لدينا لعبة – أي تحويله إلى تنسيق التي يمكن حفظها واستعادتها في وقت لاحق. لهذا، دعونا إنشاء برنامج نصي #C والذي يطلق عليه SaveLoad
. هذا البرنامج النصي سيتم التعامل مع كل وظيفة حفظ وتحميل.
ونحن سوف مرجع هذا البرنامج النصي من البرامج النصية الأخرى، فلتجعل من فئة ثابتة عن طريق إضافة ثابت
كلمة بين الجمهور
والطبقة
. دعونا أيضا إزالة: الجزء MonoBehaviour
، لأننا لا نحتاج إلى إرفاقه جاميوبجيكت
. وبما أنه لم يعد يرث من MonoBehaviour
، دعنا نحذف وظائف Start
و Update
.
يجب أن تبدو التعليمات البرمجية الناتجة كما يلي:
1 |
using UnityEngine; |
2 |
using System.Collections; |
3 |
|
4 |
public static class SaveLoad { |
5 |
|
6 |
}
|
الآن، نحن ذاهبون إلى تريد إضافة بعض الوظائف الجديدة لهذا البرنامج النصي، ذلك فورا تحت حيث تقول استخدام System.Collections
؛، يضاف ما يلي:
1 |
using System.Collections.Generic; |
2 |
using System.Runtime.Serialization.Formatters.Binary; |
3 |
using System.IO; |
يسمح لنا السطر الأول باستخدام القوائم الديناميكية في C# ، ولكن هذا ليس ضروريًا للتسلسل. السطر الثاني هو ما يمكننا من استخدام قدرات التسلسل في نظام التشغيل داخل البرنامج النصي. في السطر الثالث، IO لتقف على المدخلات والمخرجات، وهو ما يسمح لنا بالكتابة إلى والقراءه من أن الكمبيوتر أو الجهاز المحمول. بمعنى آخر ، يسمح لنا هذا السطر بإنشاء ملفات فريدة ثم القراءة من هذه الملفات لاحقًا.
نحن الآن مستعدون لإجراء تسلسل لبعض البيانات!
مما يجعل فصول قابل للتسلسل
الآن أن لدينا البرنامج النصي لديه القدرة على إجراء تسلسل، نحن ذاهبون إلى إعداد بعض الفئات يمكن إجراء تسلسل. إذا كنت تفكر في آر بي جي أساسية، مثل 'الخيال النهائي'، فإنه يقدم اللاعبين القدرة على إنشاء وتحميل مختلف الألعاب التي تم حفظها. لذلك، إنشاء برنامج نصي ج جديدة تسمى اللعبة وإعطائها بعض المتغيرات بعقد ثلاثة كائنات: فارس ومارقة ومعالج. تغيير التعليمات البرمجية للبرنامج النصي هذا البحث مثل هذا:
1 |
using UnityEngine; |
2 |
using System.Collections; |
3 |
|
4 |
[System.Serializable] |
5 |
public class Game { |
6 |
|
7 |
public static Game current; |
8 |
public Character knight; |
9 |
public Character rogue; |
10 |
public Character wizard; |
11 |
|
12 |
public Game () { |
13 |
knight = new Character(); |
14 |
rogue = new Character(); |
15 |
wizard = new Character(); |
16 |
}
|
17 |
|
18 |
}
|
الخط [System.Serializable] إعلام الوحدة أنه يمكن إجراء تسلسل هذا البرنامج النصي – وبعبارة أخرى، يمكن أن نوفر جميع المتغيرات في هذا البرنامج النصي. باردة! ووفقا لمستندات رسمية، يمكن إجراء تسلسل الوحدة الأنواع التالية:
- كافة أنواع البيانات الأساسية (مثل int والسلسله، تطفو و bool).
- بعض الأنواع المضمنة (بما في ذلك Vector2، Vector3، Vector4، الكواتيرنيون، Matrix4x4، واللون واحداثيات ولاييرماسك).
- كافة الفئات التي ترث من UnityEngine.Object (بما في ذلك جاميوبجيكت، والعنصر، مونوبيهافيور، Texture2D، وأنيماتيونكليب).
- تتضمن التعدادات.
- المصفوفات وقوائم من نوع قابل للتسلسل.
المتغير الأول، حاليا، مرجع ثابتة إلى مثيل لعبة. عندما كنا بإنشاء أو تحميل لعبة، نحن ذاهبون إلى تعيين هذا المتغير الثابت لذلك المثيل لعبة معينة بحيث أننا يمكن الرجوع إلى 'اللعبة الحالية' من أي مكان في المشروع. باستخدام المتغيرات ثابتة ووظائفها، لا يتعين علينا استخدام الدالة GetComponent() جاميوبجيكت. مفيد!
لاحظ أنه يتم الرجوع إلى شيء يسمى حرف؟ ليس لدينا هذا حتى الآن ، لذلك دعونا نصنع برنامجًا نصيًا جديدًا لإيواء هذا الصف ، ونطلق عليه الحرف:
1 |
using UnityEngine; |
2 |
using System.Collections; |
3 |
|
4 |
[System.Serializable] |
5 |
public class Character { |
6 |
|
7 |
public string name; |
8 |
|
9 |
public Character () { |
10 |
this.name = ""; |
11 |
}
|
12 |
}
|
يمكن أن يتساءل لماذا نحن بحاجة فئة جديدة كاملة إذا نحن كنت فقط تخزين متغير سلسلة. وفي الواقع، نحن يمكن أن فقط استبدال الحرف في لعبة البرنامج النصي استخدام سلسلة بدلاً من ذلك. ولكن أريد أن تظهر لك مدى عمق هذه الحفرة الأرانب يمكن الذهاب: يمكنك حفظ وتحميل الفئات التي تشير إلى فئات أخرى، وهلم جرا، ما دامت كل فئة قابل للتسلسل.
والآن بعد أن يتم إعداد الفصول حفظ وتحميل، دعونا هوب العودة أكثر إلى البرنامج النصي سافيلواد لدينا وإضافة القدرة على حفظ الألعاب.
توفير الدولة للعبة
تعرض قائمة 'تحميل اللعبة' عادةً قائمة بالألعاب المحفوظة ، لذا دعنا ننشئ قائمة من نوع اللعبة وأطلق عليها اسم saveGames. تجعل من قائمة ثابتة، حيث أن هناك قائمة واحدة فقط من الألعاب التي تم حفظها في مشروعنا. يجب أن تبدو التعليمة البرمجية كما يلي:
1 |
using UnityEngine; |
2 |
using System.Collections; |
3 |
using System.Collections.Generic; |
4 |
using System.Runtime.Serialization.Formatters.Binary; |
5 |
using System.IO; |
6 |
|
7 |
public static class SaveLoad { |
8 |
|
9 |
public static List<Game> savedGames = new List<Game>(); |
10 |
|
11 |
}
|
وبعد ذلك، دعونا إنشاء دالة ثابتة جديدة لحفظ لعبة:
1 |
public static void Save() { |
2 |
savedGames.Add(Game.current); |
3 |
BinaryFormatter bf = new BinaryFormatter(); |
4 |
FileStream file = File.Create (Application.persistentDataPath + "/savedGames.gd"); |
5 |
bf.Serialize(file, SaveLoad.savedGames); |
6 |
file.Close(); |
7 |
}
|
ويضيف سطر 2 لعبتنا الحالية لدينا قائمة من الألعاب التي تم حفظها. هذه القائمة هي ما سنسلسله. للقيام بذلك، نحتاج أولاً إلى إنشاء BinaryFormatter جديدة، التي سوف تتعامل مع عمل التسلسل. وهذا ما يفعله سطر 3.
في السطر 4، نحن تقوم بإنشاء FileStream، الذي هو أساسا مسار إلى ملف جديد أن نتمكن من إرسال البيانات أيضا، مثل الأسماك السباحة مع التيار في نهر. ونحن نستخدم File.Create() لإنشاء ملف جديد في الموقع ونحن تمرير المعلمة. مريح، الوحدة بموقع مدمج لتخزين ملفات اللعبة لدينا (ما هي التحديثات تلقائياً استناداً إلى ما هو منصة بنيت على اللعبة الخاصة بك) تشير إلى أننا يمكن استخدام Application.persistentDataPath.
نظراً لأننا تقوم بإنشاء ملف جديد، بيد أننا لا نقول فقط حيث يوجد الملف، علينا أيضا أن الغطاء قبالة هذا المسار مع اسم الملف الفعلي نفسه. هناك جزئين لهذا الملف:
- اسم الملف
- نوع الملف
سوف نستخدم سافيدجاميس لاسم الملف، وسنقوم باستخدام مخصص اكتب البيانات gd (على "بيانات اللعبة") لنوع الملف. لدينا النتيجة لعبة ملف يسمى savedGames.gd في الموقع الذي حدده Application.persistentDataPath. (في المستقبل، يمكن أن تقوم بحفظ الأنواع الأخرى من الأمور إلى هذا النوع من البيانات؛ على سبيل المثال، يمكن حفظ إعدادات خيارات المستخدمين ك options.gd).
ملاحظة: يمكنك جعل الملف اكتب أي شيء تريده. على سبيل المثال، يستخدم سلسلة مخطوطات.esm كنوع الملف الخاص به. ويمكن بسهولة كما قلتم savedGames.baconAndGravy.
في السطر 5، نحن نطلق وظيفة Serialize BinaryFormatter لحفظ قائمة سافيدجاميس إلى الملف الجديد. وبعد ذلك، علينا إغلاق الملف الذي أنشأنا، في السطر 6.
Badda بنج، بدأه بوم. يتم حفظ الألعاب.
تحميل الدولة لعبة
في الدالة، وحفظ تسلسل ونحن لدينا قائمة الألعاب التي تم حفظها في موقع معين. على العكس من ذلك، يجب أن تبدو التعليمة البرمجية لتحميل الألعاب لدينا كما يلي:
1 |
public static void Load() { |
2 |
if(File.Exists(Application.persistentDataPath + "/savedGames.gd")) { |
3 |
BinaryFormatter bf = new BinaryFormatter(); |
4 |
FileStream file = File.Open(Application.persistentDataPath + "/savedGames.gd", FileMode.Open); |
5 |
SaveLoad.savedGames = (List<Game>)bf.Deserialize(file); |
6 |
file.Close(); |
7 |
}
|
8 |
}
|
في السطر 2، يمكننا التحقق من ما إذا كان يوجد ملف لعبة محفوظة. (إذا لم يحدث ذلك، لن يكون هناك شيء لتحميل، ومن الواضح أن.) في السطر 3، نقوم بإنشاء BinaryFormatter بنفس الطريقة فعلنا في وظيفة حفظ. في السطر 4 ، نقوم بإنشاء FileStream - ولكن هذه المرة ، تسبح أسماكنا في اتجاه المنبع من الملف. وبالتالي ، فإننا نستخدم File.Open ، ونشير إلى حيث يوجد saveGames.gd الخاص بنا باستخدام نفس سلسلة Application.persistentDataPath.
السطر 5 كثيف قليلاً ، لذا دعنا نفتحه:
- تجد bf.Deserialize (ملف) المكالمة الملف في الموقع الذي حددناه أعلاه ونقوم بإلغاء تسلمه.
- لا يمكننا فقط أن نبصق binary في Unity ونتوقع أن يعمل ، لذلك نقوم بتحويل (أو إرسال) ملفنا المنتزع إلى نوع البيانات الذي نريده ، والذي في هذه الحالة هو قائمة من نوع اللعبة.
- ثم قمنا بتعيين تلك القائمة كقائمة من الألعاب المحفوظة.
أخيرًا ، في السطر 6 ، نغلق هذا الملف بنفس الطريقة التي قمنا بها في وظيفة حفظ.
ملاحظة: يمكن أن يتغير نوع البيانات الذي قمت بإدخال البيانات غير المنتهية به اعتمادًا على ما تحتاج إليه. فمثلا، (Player.lives = (int)bf.Deserialize(file;
.
خاتمة
اكتمل الآن برنامج SaveLoad
النصي الخاص بنا ، ويجب أن يظهر بالشكل التالي:
1 |
using UnityEngine; |
2 |
using System.Collections; |
3 |
using System.Collections.Generic; |
4 |
using System.Runtime.Serialization.Formatters.Binary; |
5 |
using System.IO; |
6 |
|
7 |
public static class SaveLoad { |
8 |
|
9 |
public static List<Game> savedGames = new List<Game>(); |
10 |
|
11 |
//it's static so we can call it from anywhere
|
12 |
public static void Save() { |
13 |
SaveLoad.savedGames.Add(Game.current); |
14 |
BinaryFormatter bf = new BinaryFormatter(); |
15 |
//Application.persistentDataPath is a string, so if you wanted you can put that into debug.log if you want to know where save games are located
|
16 |
FileStream file = File.Create (Application.persistentDataPath + "/savedGames.gd"); //you can call it anything you want |
17 |
bf.Serialize(file, SaveLoad.savedGames); |
18 |
file.Close(); |
19 |
}
|
20 |
|
21 |
public static void Load() { |
22 |
if(File.Exists(Application.persistentDataPath + "/savedGames.gd")) { |
23 |
BinaryFormatter bf = new BinaryFormatter(); |
24 |
FileStream file = File.Open(Application.persistentDataPath + "/savedGames.gd", FileMode.Open); |
25 |
SaveLoad.savedGames = (List<Game>)bf.Deserialize(file); |
26 |
file.Close(); |
27 |
}
|
28 |
}
|
29 |
}
|
هذه هي أساسيات الادخار والتحميل في الوحدة. في ملف المشروع المرفق ، ستجد بعض البرامج النصية الأخرى التي توضح كيف أتعامل مع استدعاء هذه الوظائف وكيف يمكنني عرض البيانات باستخدام واجهة المستخدم الرسومية لـ Unity.