الوحدة لديها نظام جيد لإنشاء واجهة مستخدم UI Canvas. تمت كتابة الكثير من المواد التدريبية عليها ، لكن معظم الأدلة تخبرك فقط بالأزرار التي يجب الضغط عليها وأي كود للكتابة لجعله يعمل. على سبيل المثال ، تتكون الواجهة الصغيرة عادة من زوج من النوافذ: القائمة الرئيسية ، الإعدادات. ومع ذلك ، في الألعاب يوجد عدد أكبر بكثير من النوافذ ، وعندما يكون هناك بالفعل ما لا يقل عن عشرة منها ، تنشأ الحاجة إلى نوع من التنظيم. كجزء من هذا المقال ، أريد أن أتحدث عن كيفية حل هذه المشكلة.
تحتاج أولاً إلى تحديد الإطارات الفردية في واجهتك. بواسطة نافذة أعني لوحة مع بعض الضوابط.
يجب أن يحتوي كل نافذة على كائن الجذر الذي سيحتوي على كافة عناصر التحكم. سيمثل هذا الكائن النافذة ككل. على سبيل المثال ، هناك لوحة توجد عليها عناصر التحكم ، من المنطقي جعل هذه العناصر تابعة فيما يتعلق باللوحة. يتم إرفاق مكون بكل نافذة ، وهو سليل فئة النافذة المجردة.
نافذة
يتم كتابة النافذة على افتراض أن النوافذ يمكن أن تحتوي على نوافذ فرعية ، أي تلك النوافذ التي يمكن فتحها من النافذة الحالية في نفس الوقت في نفس الوقت يمكن فتح نافذة فرعية واحدة ، ويجب إغلاق كل البقية. لهذا الغرض ، تحتوي الفئة على خاصية CurrentWindow حيث يتم تخزين ارتباط الإطار المفتوح حاليًا. وهناك أيضًا حدث OnOpen يُبلغ عن فتح نافذة. يمكن الاشتراك في أسلوب ChangeCurrentWindow () لهذا الحدث بالقرب من النوافذ الفرعية ، بحيث يتم فتح نافذة فرعية واحدة في أي وقت ، ويغلق الإطار الفرعي المفتوح ويغير الرابط إلى النافذة المفتوحة الحالية ، وسأقدم أدناه مثالاً على التنفيذ. يوجد أيضًا في الفصل طرق SelfClose () و SelfOpen () ، هذه الطرق مسؤولة عن كيفية فتح وإغلاق النافذة. في طريقة Awake () ، يتم تسجيل النافذة في UIManager ، أي يتم إضافة رابط إلى النافذة.
public abstract class Window : MonoBehaviour { public bool IsOpen { get; private set; } public Window CurrentWindow { get; protected set; } = null; public delegate void OpenEventHandler(Window sender); public event OpenEventHandler OnOpen; void Awake() { UIManager.Instance.Windows.Add(this.gameObject); } public void Open() { IsOpen = true; if (OnOpen != null) OnOpen(this); SelfOpen(); } protected abstract void SelfOpen(); public void Close() { IsOpen = false; if (CurrentWindow != null) CurrentWindow.Close(); SelfClose(); } protected abstract void SelfClose(); protected void ChangeCurrentWindow(Window sender) { if (CurrentWindow != null) CurrentWindow.Close(); CurrentWindow = sender; } }
UIManager
بعد ذلك ، ننتقل إلى فئة UIManager ، إنها فئة sigleton بحيث يمكن لجميع النوافذ الوصول إليها إذا لزم الأمر. كما ترون ، فإنه يحتوي على قائمة من نوافذ ويندوز ، فإنه يخزن الروابط لجميع النوافذ على المسرح. هناك حاجة إلى InitUI () لتهيئة شيء ما ، على سبيل المثال ، إذا كنت ترغب في إنشاء نوافذ من المباني الجاهزة ، يمكنك هنا القيام بمثيلاتها.
في طريقة البدء () ، يمكنك فتح نوافذ يجب أن تكون مفتوحة من البداية ، أو العكس من إغلاق النوافذ غير الضرورية. تتيح لك طريقة Get () الحصول على رابط إلى نافذة محددة.
using System.Collections; using System.Collections.Generic; using UnityEngine; using System; public class UIManager : MonoBehaviour { public static UIManager Instance = null; public List<GameObject> Windows; void Awake() { if (Instance == null) Instance = this; else if (Instance != this) Destroy(gameObject); InitUI(); } private void InitUI() {
SettingsWindow
على سبيل المثال ، سأقدم تطبيق نافذة الإعدادات:
using System.Collections; using System.Collections.Generic; using UnityEngine; public class SettingsWindow : Window { private VideoSettingsWindow videoSettingsWindow; private LanguageSettingsWindow languageSettingsWindow; private AudioSettingsWindow audioSettingsWindow; private ControlSettingsWindow controlSettingsWindow; public void Start() { videoSettingsWindow = UIManager.Instance.GetWindow<VideoSettingsWindow>(); languageSettingsWindow = UIManager.Instance.GetWindow<LanguageSettingsWindow>(); audioSettingsWindow = UIManager.Instance.GetWindow<AudioSettingsWindow>(); controlSettingsWindow = UIManager.Instance.GetWindow<ControlSettingsWindow>(); videoSettingsWindow.OnOpen += ChangeCurrentWindow; languageSettingsWindow.OnOpen += ChangeCurrentWindow; audioSettingsWindow.OnOpen += ChangeCurrentWindow; controlSettingsWindow.OnOpen += ChangeCurrentWindow; } protected override void SelfOpen() { this.gameObject.SetActive(true); } protected override void SelfClose() { this.gameObject.SetActive(false); } public void Apply() { } public void VideoSettings() { videoSettingsWindow.Open(); } public void LanguageSettings() { languageSettingsWindow.Open(); } public void AudioSettings() { audioSettingsWindow.Open(); } public void ControlSettings() { controlSettingsWindow.Open(); } }
من نافذة الإعدادات ، يمكنني فتح 4 نوافذ أخرى بحيث يتم فتح نافذة واحدة فقط ، وأنا أشارك طريقة ChangeCurrentWindow () لإطار الإعدادات في أحداث OnOpen الخاصة بالنوافذ الفرعية ، لذلك يتم إغلاق النوافذ المفتوحة عند فتح الآخرين. تقوم تطبيقات SelfOpen () و SelfClose () ببساطة بتنشيط النافذة أو إلغاء تنشيطها.
وبالتالي ، يتم الحصول على نظام واجهة مستخدم سهل الامتداد ، ليست هناك حاجة لإضافة روابط إلى النوافذ يدويًا في المفتش أو في أي مكان آخر ، لإضافة نافذة جديدة ، تحتاج فقط إلى إنشاء الفئة المناسبة وترثها من النافذة. يحتوي مثل هذا النظام على بضع سطور ، فكلما زاد عدد النوافذ ، زاد عدد الفئات التي سيكون من الضروري إنشاؤها وحقيقة أن البحث عن رابط للإطار يحدث عن طريق الفرز عبر مجموعة من الروابط ، ولكن في رأيي هذه العيوب تؤتي ثمارها.
مستودع الرابط