MVC (Model-View-Controller) عبارة عن مخطط يتضمن تقسيم بيانات التطبيق وواجهة المستخدم ومنطق التحكم إلى ثلاثة مكونات منفصلة بحيث يمكن تعديل كل منها بشكل مستقل. تبادل المطور
Cem Ugur Karacam خبرته في البرمجة في Unity وتحدث باختصار عن الأشياء القابلة للبرمجة. نقدم ترجمة لمقاله المنشور على dev.to.

مرحبًا بك في الجزء الأول من حديثي حول تطبيق MVC في الوحدة باستخدام كائنات Scriptable. في هذه المقالة كتبت فقط عن أساسيات العمل مع الكائنات القابلة للبرمجة ، وبشكل عام سيكون النص بسيطًا وواضحًا.
أولاً ، اكتشف ما يقوله مطورو الوحدة حول الكائنات القابلة للبرمجة:
- هذه فئة يمكن توريثها لإنشاء كائن لا يجب إرفاقه بكائن آخر في المشهد.
- أكبر فائدة من هذا الكائن الذي تم إنشاؤه ستكون إذا كنت تستخدمه فقط لحفظ البيانات.
من المنطقي الآن أن نسأل: لماذا الكائنات القابلة للبرمجة؟
تعد الكائنات القابلة للبرمجة جزءًا من وظائف مشغل Unity ، لذلك فإن هذه الكائنات لها العديد من الميزات المضمنة للعمل مع المحرر.
تعجبني الطريقة المتبعة عند تطوير المشروعات على الوحدة. يمكنك إنشاء الأدوات الخاصة بك وتخصيص الأدوات المثبتة بشكل افتراضي بسهولة. تقوم الكائنات القابلة للبرمجة بتوسيع قدراتك بشكل كبير ، لأنها تتيح لك إنشاء حاويات مخصصة للبيانات وتخزينها كأصول في المشروع.

الصورة أعلاه هي مثال لاستخدام كائن Scriptable في الوحدة. قد يحتوي ملف .asset واحد الذي تم إنشاؤه في مشروع ما على المعلومات اللازمة لتشغيل عدة أنظمة وضمان الحفاظ على إعداداتها. إذا كنت تريد معرفة المزيد ، فهناك فيديو ممتاز على YouTube مع عرض تقديمي حول SO (كائن
نصي ) بعنوان "
إسقاط MonoBehaviour Tyranny في ثورة كائن Scriptable رائعة ".

مثال رائع آخر مبين أعلاه. هنا ، تشير كائنات اللعبة إلى كائن الجرد ، ويقوم نظام الحفظ بإدارتها جميعًا. هذه الصورة مأخوذة من محاضرة ممتازة أخرى ، "هندسة الألعاب مع الكائنات القابلة للبرمجة" (
هندسة الألعاب باستخدام الكائنات القابلة للبرمجة ) ، أوصي بشدة بقراءتها.
ميزة أخرى رائعة هي أنه عندما تفهم كائنات Scriptable ، فأنت على الأرجح لا ترغب في استخدام تنسيقات تخزين البيانات الأخرى ، مثل JSON أو XML ، لأن SO هو التنسيق الأنسب لتخزين البيانات في Unity.
حسنًا ، لنلقِ نظرة على الكائنات النصية أثناء العمل.
using UnityEngine; public class ItemData : ScriptableObject { public string itemName; public ItemType type; public float attack; } public enum ItemType { Dagger, Axe, Sword, Staff }
لقد كتبنا فئة تسمى
ItemData
والعديد من الخصائص النموذجية لألعاب آر بي جي. بعد ذلك ، سنقوم بإنشاء العديد من هذه العناصر في المشروع ، والوصول إليها من البرنامج النصي وعرض القيم في وحدة التحكم. لكن أولاً ، أضف سطرًا مهمًا إلى الكود الخاص بنا.
using UnityEngine; [CreateAssetMenu] public class ItemData : ScriptableObject { public string itemName; public ItemType type; public float attack; } public enum ItemType { Dagger, Axe, Sword, Staff }
CreateAssetMenu
السمة
CreateAssetMenu
التي أضفناها قبل فئة
ItemData
إلى الوحدة بأننا نريد إنشاء ملفات .asset يتم تخزين فئتنا بها من خلال القائمة. وإلا ، فلن نتمكن من القيام بذلك باستخدام زر الماوس الأيمن أو الزر "إنشاء" في مجلد المشروع.


إنشاء مجلد يسمى
Items
ومحاولة إنشاء كائن
ItemData
في هذا المجلد.

سنقوم الآن بكتابة برنامج نصي آخر يسمى
Inventory
للعمل مع ملف البيانات.
using UnityEngine; public class Inventory : MonoBehaviour { public ItemData[] inventory; }
أضف طريقة إليه ستقوم بإخراج المعلومات إلى وحدة التحكم. نقوم أيضًا بإجراء فحص حتى لا تتجاوز حدود المصفوفة ، ولكن لتجاوز المصفوفة في دائرة.
using UnityEngine; public class Inventory : MonoBehaviour { public ItemData[] inventory; int index = 0; public void NextItemInfo() { if (index > inventory.Length) { index = 0; } Debug.Log("Item name: " + inventory[index].name); Debug.Log ("Attack power: " + inventory[index].attack); switch(inventory[index].type) { case ItemType.Axe: Debug.Log("Item type: Axe"); break; case ItemType.Dagger: Debug.Log("Item type: Dagger"); break; case ItemType.Staff: Debug.Log("Item type: Staff"); break; case ItemType.Sword: Debug.Log("Item type: Sword"); break; } index ++; } }
سأقوم بتعيين مكالمة إلى طريقتنا إلى شريط المسافة. في الوحدة ، هذا سهل للغاية. بفضل فئة
Input
، يمكننا التحقق من طريقة
Update
ما إذا كان قد تم الضغط على المفتاح المطلوب.
using UnityEngine; public class Inventory : MonoBehaviour { public ItemData[] inventory; int index = 0; private void Update() { if (Input.GetKeyDown(KeyCode.Space)) { NextItemInfo(); } } public void NextItemInfo() { if (index > inventory.Length) { index = 0; } Debug.Log("Item name: " + inventory[index].name); Debug.Log ("Attack power: " + inventory[index].attack); switch(inventory[index].type) { case ItemType.Axe: Debug.Log("Item type: Axe"); break; case ItemType.Dagger: Debug.Log("Item type: Dagger"); break; case ItemType.Staff: Debug.Log("Item type: Staff"); break; case ItemType.Sword: Debug.Log("Item type: Sword"); break; } index ++; } }
حان الوقت للعودة إلى محرر الوحدة. سنقوم بتعبئة مجموعة
inventory
بنا بملفات
ItemData
تم إنشاؤها مسبقًا من مجلد
Items
. لكن أولاً ، أنشئ كائنًا فارغًا في المشهد وأضف برنامج
Inventory
بنا إليه.

الآن لنشغل المشروع ونختبره.

إنه يعمل! والآن أريد أن أوضح لك أن الكائن القابل للبرمجة لا يمكنه تخزين البيانات فحسب ، ولكن أيضًا طرق التعامل معها. على سبيل المثال ، دعنا نضيف طريقة لحساب السعر في فئة
ItemData
. لمزيد من المعلومات حول هذا ، تحقق من مستندات
هنا وهنا .
using UnityEngine; [CreateAssetMenu] public class ItemData : ScriptableObject { public string itemName; public ItemType type; public float attack; public float GetPrice() { return attack * 40; } }
ثم نستخدم طريقة جديدة لدينا في فئة
Inventory
.
using UnityEngine; public class Inventory : MonoBehaviour { public ItemData[] inventory; int index = 0; private void Update() { if (Input.GetKeyDown(KeyCode.Space)) { NextItemInfo(); } } public void NextItemInfo() { if (index == inventory.Length) { index = 0; } Debug.Log("Item name: " + inventory[index].name); Debug.Log ("Attack power: " + inventory[index].attack); switch(inventory[index].type) { case ItemType.Axe: Debug.Log("Item type: Axe"); break; case ItemType.Dagger: Debug.Log("Item type: Dagger"); break; case ItemType.Staff: Debug.Log("Item type: Staff"); break; case ItemType.Sword: Debug.Log("Item type: Sword"); break; } Debug.Log("Item price: " + inventory[index].GetPrice()); index ++; } }
الآن سوف نعيد إنتاج كل شيء وننظر إلى النتيجة.

أمثلة من هذا البرنامج التعليمي على
GitHub !
انتهى الجزء الأول من القصة. في المقالة التالية ، سنتحدث عن استخدام MVC في الوحدة. ولكن نظرًا لأننا على دراية بالأشياء القابلة للبرمجة بالفعل ، فسنضيف بعض الميزات الجديدة لجعلها أكثر برودة وصعوبة مثلما يفعل معلمو الوحدة الحقيقية.