MVC في الوحدة مع كائنات Scriptable. الجزء 3

إكمال سلسلة من المقالات كتبها Cem Ugur Karacam على تطبيق MVC في الوحدة باستخدام كائنات Scriptable. يمكنك قراءة الأجزاء السابقة هنا وهنا .



هذه هي المرحلة الأخيرة من مشروعنا.

حاولت عمل رسم تخطيطي لتوضيح سير عمل MVC في الوحدة.



في تطبيق Unity ، توجد كائنات MonoBehaviour في المشهد ، حتى تتمكن من رؤية التسلسل الهرمي الخاص بها. ولكن هذه الأشياء لا يمكن التواصل مع بعضها البعض مباشرة. نمط الوحدة MVC هو الحل لهذه المشكلة.

ببساطة: يأتي إدخال المستخدم إلى وحدة التحكم ، مما ينشئ طريقة عرض للنموذج ، ويعرض العرض بيانات النموذج على الشاشة.

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

دعنا نواصل المشروع مع ما استقرنا عليه في المقال الأخير. سنعمل على العرض التقديمي. سوف أقوم بإنشاء لوحة تحتوي على كائنات واجهة المستخدم.



لدينا لوحة ، كائن صورة لرمز العنصر ، وثلاثة كائنات نصية لعرض اسم الهجوم ونوعه وقوته. لإدارة هذه الكائنات ، قم بإنشاء فصل في المشروع يسمى InfoView وإضافته إلى المشهد.



إضافة روابط لعناصر واجهة.

 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class InfoView : MonoBehaviour { public Image icon; public Text nameText; public Text typeText; public Text attackText; } 

ثم قم بإنشاء طريقة التهيئة لتكوين هذه العناصر وفقًا للإدخال.

 using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class InfoView : MonoBehaviour { public Image icon; public Text nameText; public Text typeText; public Text attackText; public void Init(ItemData data) { icon.sprite = data.icon; nameText.text = data.name; attackText.text = "Attack Power: " + data.attack; switch (data.type) { case ItemType.Axe: typeText.text = "Type: Axe"; break; case ItemType.Dagger: typeText.text = "Type: Dagger"; break; case ItemType.Hammer: typeText.text = "Type: Hammer"; break; case ItemType.Potion: typeText.text = "Type: Potion"; break; } } } 

الآن تعيين الحقول في المحرر.



نحن على استعداد لعمل الجاهزة من وجهة النظر هذه. قمت بإنشاء مجلد يسمى Resources . هذا مجلد خاص يسمح للوحدة بتنزيل الملفات منه من خلال واجهة برمجة تطبيقات خاصة. ضع الجاهزة لدينا في مجلد Resources .



بما أنني سأستخدم الجاهزة ، فسأزيل InfoView من المشهد.



الوقت لفتح وحدة تحكم.

سأضيف تحويلًا عامًا متغيرًا لمعرفة أي كائن سيكون هو الأصل لهذا العرض ، ومتغير خاص للحفاظ على الرابط الخاص بـ InfoView عند بدء التشغيل.

 using System.Collections; using System.Collections.Generic; using UnityEngine; public class ItemViewController : MonoBehaviour { public Inventory inventoryHolder; public Transform inventoryViewParent; public Transform infoViewParent; private GameObject infoViewPrefab; private GameObject itemViewPrefab; private void Start() { itemViewPrefab = (GameObject)Resources.Load("Item"); infoViewPrefab = (GameObject)Resources.Load("InfoView"); } } 

دعنا نكتب طريقة لإنشاء حالات مشاهدة في مشهد ما.

 private void CreateInfoView(ItemData data) { var infoGO = GameObject.Instantiate(infoViewPrefab, infoViewParent); infoGO.GetComponent<InfoView>().Init(data); } 

ItemView طريقة ItemView هذه إلى InitItem باستخدام الأحداث في C #. لتحقيق ذلك ، قم بتغيير ItemView قليلاً.

 using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class ItemView : MonoBehaviour { public Button button; public Image itemIcon; private ItemData itemData; public void InitItem(ItemData item, Action<ItemData> callback) { this.itemData = item; itemIcon.sprite = itemData.icon; button.onClick.AddListener(() => callback(itemData) ); } } 

أضفت معلمة لتمرير الطريقة. والآن يمكنك توصيل وحدة التحكم.

 using System.Collections; using System.Collections.Generic; using UnityEngine; public class ItemViewController : MonoBehaviour { public Inventory inventoryHolder; public Transform inventoryViewParent; public Transform infoViewParent; private GameObject infoViewPrefab; private GameObject itemViewPrefab; private void Start() { itemViewPrefab = (GameObject)Resources.Load("Item"); infoViewPrefab = (GameObject)Resources.Load("InfoView"); foreach (var item in inventoryHolder.inventory) { var itemGO = GameObject.Instantiate(itemViewPrefab, inventoryViewParent); itemGO.GetComponent<ItemView>().InitItem(item, CreateInfoView); } } private void CreateInfoView(ItemData data) { var infoGO = GameObject.Instantiate(infoViewPrefab, infoViewParent); infoGO.GetComponent<InfoView>().Init(data); } } 

في طريقة البدء ، قمت بتعبئة المخزون بالعناصر ، وعند النقر فوق أحدهما ، سيتم استدعاء طريقة CreateInfoView . ولكن قبل أن نبدأ في اختبار هذا ، سأوجهك إلى مشكلة واحدة. لا تعرف وحدة التحكم ما إذا كنا قد أنشأنا InfoView قبل. دعونا إصلاحه.

 using System.Collections; using System.Collections.Generic; using UnityEngine; public class ItemViewController : MonoBehaviour { public Inventory inventoryHolder; public Transform inventoryViewParent; public Transform infoViewParent; private GameObject infoViewPrefab; private GameObject itemViewPrefab; private GameObject infoView; private void Start() { itemViewPrefab = (GameObject)Resources.Load("Item"); infoViewPrefab = (GameObject)Resources.Load("InfoView"); foreach (var item in inventoryHolder.inventory) { var itemGO = GameObject.Instantiate(itemViewPrefab, inventoryViewParent); itemGO.GetComponent<ItemView>().InitItem(item, CreateInfoView); } } private void CreateInfoView(ItemData data) { if (infoView != null) { Destroy(infoView); } infoView = GameObject.Instantiate(infoViewPrefab, infoViewParent); infoView.GetComponent<InfoView>().Init(data); } } 

لقد infoView متغير infoView قبل إنشاء مثيل جديد لـ InfoView في المشهد.

دعونا اختباره.



يبدو أننا فعلنا ذلك!

مشروع على جيثب .

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

أعتقد أننا قد لا نستخدم القوالب على الإطلاق ، ولكن بعد ذلك لن نكون مختلفين عن العصور الوسطى. :)

على أي حال ، نظرًا لاستكمال هذه السلسلة من المقالات ، أقترح عليك قراءة نصوصي الأخرى التي تتحدث أيضًا عن نمط MVC والكائنات القابلة للبرمجة: إنشاء خدمة REST باستخدام Node و Express لاستخدامها مع Unity .

هذا كل شيء. ترميز جيد!

Source: https://habr.com/ru/post/ar479550/


All Articles