الاستفادة من ميزة "الإعداد عن بُعد في Firebase" في تحسين ألعاب Unity

1. مقدمة

يمكنك استخدام ميزة "الإعداد عن بُعد في Firebase" من أجل تحديد أزواج المفتاح/القيمة، المعروفة أيضًا باسم المَعلمات، في تطبيقك وتعديل قيمها على السحابة الإلكترونية، ما يتيح لك تعديل مظهر تطبيقك وطريقة عمله بدون توزيع تحديث للتطبيق.

ستضيف هذه الوظيفة الجديدة إلى لعبة نموذجية، وهي MechaHamster: Level Up with Firebase Edition. هذه اللعبة النموذجية هي إصدار جديد من لعبة MechaHamster الكلاسيكية على Firebase، وهي تزيل معظم وظائف Firebase المضمّنة، ما يمنحك الفرصة لتنفيذ استخدامات جديدة لـ Firebase بدلاً منها.

لضمان عمل تطبيقك على النحو المنشود، عليك ضبط الإعدادات التلقائية للقيم في نموذج رمز اللعبة، ويمكن إلغاء هذه القيم بالقيم التي تحدّدها في ميزة "الإعداد عن بُعد" في وحدة تحكّم Firebase.

أهداف الدورة التعليمية

  • كيفية ضبط قيم "الإعداد عن بُعد" في السحابة الإلكترونية واسترجاعها
  • كيفية إعداد رمز Unity C# لاستخدام القيم التي تم استردادها تلقائيًا
  • كيفية تخزين القيم/الكائنات المركّبة وتفعيلها وتجاوزها كقيم JSON
  • كيفية استخدام شروط "الإعداد عن بُعد" لعرض صيغ قيم مختلفة لمجموعات مختلفة من المستخدمين

المتطلبات

  • الإصدار 2019.1.0f1 أو الإصدارات الأحدث من Unity مع إمكانية إنشاء إصدارات متوافقة مع iOS و/أو Android
  • جهاز Android/iOS فعلي أو محاكي لإنشاء اللعبة وتشغيلها

2. إعداد بيئة التطوير

توضّح الأقسام التالية كيفية تنزيل رمز تطوير المهارات باستخدام Firebase وفتحه في Unity وإضافة مشروع Firebase. تستخدم العديد من برامج الترميز الأخرى في Firebase وUnity لعبة Level Up with Firebase النموذجية هذه، لذا ربما تكون قد أكملت المهام في هذا القسم من قبل. إذا كان الأمر كذلك، يمكنك تخطّي هذه الخطوات والمتابعة إلى إضافة حِزم تطوير البرامج (SDK) لمنصة Firebase إلى Unity لإضافة ميزة "الإعداد عن بُعد" إلى رمز اللعبة النموذجية.

تنزيل الرمز

استنسِخ مستودع GitHub الخاص بهذا الدرس العملي من سطر الأوامر:

git clone https://github.com/firebase/level-up-with-firebase

بدلاً من ذلك، إذا لم يكن git مثبّتًا لديك، يمكنك تنزيل المستودع كملف ZIP.

افتح Level Up with Firebase في محرِّر Unity

  1. شغِّل Unity Hub، ومن علامة التبويب المشاريع، انقر على سهم القائمة المنسدلة بجانب فتح.
  2. انقر على إضافة مشروع من القرص.
  3. انتقِل إلى الدليل الذي يحتوي على الرمز، ثم انقر على حسنًا.
  4. إذا طُلب منك ذلك، اختَر إصدارًا من "محرّر Unity" لاستخدامه والنظام الأساسي المستهدف (Android أو iOS).
  5. انقر على اسم المشروع، level-up-with-firebase، وسيتم فتح المشروع في "محرّر Unity".
  6. إذا لم يفتح المحرّر تلقائيًا، افتح MainGameScene في الأصول (Assets) > Hamster في علامة التبويب المشروع (Project) في Unity Editor.

لمزيد من المعلومات حول تثبيت Unity واستخدامه، يُرجى الاطّلاع على العمل في Unity.

3- إضافة Firebase إلى مشروع Unity

إنشاء مشروع Firebase

  1. سجِّل الدخول إلى وحدة تحكّم Firebase باستخدام حسابك على Google.
  2. انقر على الزر لإنشاء مشروع جديد، ثم أدخِل اسم المشروع (على سبيل المثال، LevelUpWithFirebase).
  3. انقر على متابعة.
  4. إذا طُلب منك ذلك، راجِع بنود Firebase واقبلها، ثم انقر على متابعة.
  5. (اختياري) فعِّل ميزة "المساعدة المستندة إلى الذكاء الاصطناعي" في وحدة تحكّم Firebase (المعروفة باسم "Gemini في Firebase").
  6. في هذا الدرس العملي، تحتاج إلى "إحصاءات Google" لاستخدام منتجات Firebase على النحو الأمثل، لذا أبقِ زر التبديل مفعّلاً لخيار "إحصاءات Google". اتّبِع التعليمات الظاهرة على الشاشة لإعداد "إحصاءات Google".
  7. انقر على إنشاء مشروع، وانتظِر إلى أن يتم توفير مشروعك، ثم انقر على متابعة.

تسجيل تطبيقك في Firebase

  1. افتح وحدة تحكّم Firebase، وانقر على رمز Unity من وسط صفحة نظرة عامة على المشروع لتشغيل سير عمل الإعداد، أو انقر على إضافة تطبيق لعرض خيارات النظام الأساسي إذا سبق لك إضافة تطبيق إلى مشروعك على Firebase.
  2. اختَر تسجيل كلّ من أهداف إنشاء Apple (iOS) وAndroid.
  3. أدخِل أرقام التعريف الخاصة بمنصّة مشروع Unity. بالنسبة إلى هذا الدرس التطبيقي حول الترميز، أدخِل ما يلي:
  4. يمكنك اختياريًا إدخال الأسماء المستعارة الخاصة بالنظام الأساسي لمشروع Unity.
  5. انقر على تسجيل التطبيق وانتقِل إلى قسم تنزيل ملف الإعداد.
  6. كرِّر العملية لأي إصدار مستهدف لم تنفّذه في المرة الأولى.

إضافة ملفات إعداد Firebase

بعد النقر على تسجيل التطبيق، سيُطلب منك تنزيل ملفَّي إعداد (ملف إعداد واحد لكل هدف إنشاء). يحتاج مشروع Unity إلى بيانات Firebase الوصفية في هذه الملفات للربط بخدمة Firebase.

  1. نزِّل ملفَي الإعداد المتاحَين:
    • على أجهزة Apple (iOS): نزِّل الملف GoogleService-Info.plist.
    • على Android: نزِّل ملف google-services.json.
  2. افتح نافذة المشروع في مشروع Unity، ثم انقل ملفَي الإعداد إلى مجلد الأصول.
  3. ارجع إلى وحدة تحكّم Firebase، وفي سير عمل الإعداد، انقر على التالي وانتقِل إلى إضافة حِزم تطوير البرامج (SDK) لمنصّة Firebase إلى Unity.

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

إضافة حِزم Firebase SDK لـ Unity

  1. انقر على تنزيل حزمة تطوير البرامج (SDK) لمنصة Firebase Unity في وحدة تحكّم Firebase.
  2. فكّ ضغط حزمة تطوير البرامج (SDK) في مكان مناسب.
  3. في مشروع Unity المفتوح، انتقِل إلى الأصول (Assets) > استيراد حزمة (Import Package) > حزمة مخصّصة (Custom Package).
  4. في مربّع الحوار استيراد حزمة، انتقِل إلى الدليل الذي يحتوي على حزمة تطوير البرامج (SDK) التي تم فك ضغطها، واختَر FirebaseAnalytics.unitypackage، ثم انقر على فتح.
  5. من مربّع الحوار استيراد حزمة Unity الذي يظهر، انقر على استيراد.
  6. كرِّر الخطوات السابقة لاستيراد الحزمتَين التاليتَين:
    • FirebaseRemoteConfig.unitypackage
    • FirebaseCrashlytics.unitypackage
      ‏Crashlytics هي أداة خفيفة الوزن لإعداد تقارير الأعطال في الوقت الفعلي، وتساعدك في تتبُّع مشاكل الثبات التي تؤدي إلى تدهور جودة تطبيقك وتحديد أولويتها وحلّها. إذا لم يسبق لك استخدامها، ننصحك بإكمال مسار التعلّم في Crashlytics لـ Unity.
  7. ارجع إلى "وحدة تحكّم Firebase"، وانقر على التالي في سير عمل الإعداد.

لمزيد من المعلومات عن إضافة حِزم تطوير البرامج (SDK) من Firebase إلى مشاريع Unity، اطّلِع على خيارات تثبيت Unity الإضافية.

4. ضبط الإعدادات التلقائية في "الإعداد عن بُعد" واسترجاع قيم جديدة

في هذا الدرس العملي، ستعدّل الكائنات التي تستخدم القيم المحدّدة في الرمز أو التي يتم تسلسلها في أداة Unity لتعديل القيم التي تم قياسها باستخدام "الإعداد عن بُعد". ستضبط القيم التلقائية لكل مَعلمة باستخدام SetDefaultsAsync لكي يتصرف تطبيقك على النحو المطلوب قبل أن يتصل بخلفية "الإعداد عن بُعد". سيظل تطبيقك محدّثًا من خلال استرجاع قيم جديدة من "الإعداد عن بُعد" وتفعيلها لتصبح قابلة للاستخدام في الرمز.

لاسترجاع قيم جديدة من "الإعداد عن بُعد"، هناك عدد من الطرق غير المنفَّذة والموجودة حاليًا في ملف Assets/Hamster/Scripts/MainGame.cs يجب إكمالها.

  1. أضِف عبارات using التالية إلى MainGame.cs:
    using Firebase.Crashlytics;
    using Firebase.Extensions;
    using Firebase.RemoteConfig;
    
    يحتوي الوحدة Firebase.Extensions على بعض الإضافات إلى واجهة برمجة التطبيقات C# Tasks API التي ستساعد في تسهيل إدارة عملية التهيئة باستخدام عمليات رد الاتصال.
  2. أضِف عملية إعداد Firebase إلى طريقتك MainGame.cs Start() من خلال استبدال الطريقة الحالية InitializeCommonDataAndStartGame() بالطريقة غير المضمّنة حاليًا، InitializeFirebaseAndStartGame():
    void Start()
    {
       Screen.SetResolution(Screen.width / 2, Screen.height / 2, true);
       InitializeFirebaseAndStartGame();
    }
    
  3. في MainGame.cs، ابحث عن InitializeFirebaseAndStartGame(). عرِّف متغيّرًا للتطبيق وأعِد كتابة تنفيذ الطريقة على النحو التالي:
    public Firebase.FirebaseApp app = null;
    
    // Begins the firebase initialization process and afterwards, opens the main menu.
    private void InitializeFirebaseAndStartGame()
    {
       Firebase.FirebaseApp.CheckAndFixDependenciesAsync()
       .ContinueWithOnMainThread(
          previousTask =>
          {
             var dependencyStatus = previousTask.Result;
             if (dependencyStatus == Firebase.DependencyStatus.Available) {
             // Create and hold a reference to your FirebaseApp,
             app = Firebase.FirebaseApp.DefaultInstance;
             // Set the recommended Crashlytics uncaught exception behavior.
             Crashlytics.ReportUncaughtExceptionsAsFatal = true;
             SetRemoteConfigDefaults();
             } else {
             UnityEngine.Debug.LogError(
                $"Could not resolve all Firebase dependencies: {dependencyStatus}\n" +
                "Firebase Unity SDK is not safe to use here");
             }
          });
    }
    
  4. تُجري عمليات إعداد Firebase مكالمات SetRemoteConfigDefaults عند النجاح لضبط القيم التلقائية داخل التطبيق. استبدِل الدالة البرمجية SetRemoteConfigDefaults غير المنفَّذة بما يلي:
    private void SetRemoteConfigDefaults()
    {
       var defaults = new System.Collections.Generic.Dictionary < string, object > ();
       defaults.Add(
          Hamster.MapObjects.AccelerationTile.AccelerationTileForceKey,
          Hamster.MapObjects.AccelerationTile.AccelerationTileForceDefault);
       defaults.Add(
          Hamster.States.MainMenu.SubtitleOverrideKey,
          Hamster.States.MainMenu.SubtitleOverrideDefault);
       var remoteConfig = FirebaseRemoteConfig.DefaultInstance;
       remoteConfig.SetDefaultsAsync(defaults).ContinueWithOnMainThread(
          previousTask =>
          {
             FetchRemoteConfig(InitializeCommonDataAndStartGame);
          }
       );
    }
    

5- استرجاع القيم الجديدة وتفعيلها (حسب الحاجة)

علينا الآن إكمال طريقة FetchRemoteConfig الحالية. سيؤدي ذلك إلى ربط طلبات بطُرق "الإعداد عن بُعد" FetchAsync (التي تسترجِع قيمًا جديدة من "الإعداد عن بُعد") وActivateAsync (التي تفعّل القيم التي تم الحصول عليها لإتاحتها في الرمز) باستخدام مَعلمة ردّ الاتصال المسماة onFetchAndActivateSuccessful.

يستدعي رمز بدء التشغيل الذي أضفناه في الخطوة السابقة FetchRemoteConfig مع InitializeCommonDataAndStartGame كدالة رد الاتصال لبدء اللعبة في نهاية التسلسل. يمكنك تمرير عمليات ردّ اتصال بديلة إلى FetchRemoteConfig من أجل استدعاء عملية الجلب بنتائج مختلفة. أحد الأمثلة (الذي ستنفّذه لاحقًا) هو تمرير طريقة تفتح قوائم جديدة لواجهة المستخدم، والتي تعتمد على قيم "الإعداد عن بُعد". سيؤدي ذلك إلى عدم فتح القوائم إلا بعد استرداد هذه القيم وتفعيلها.

  1. ألصِق الرمز أدناه في FetchRemoteConfig:
    public void FetchRemoteConfig(System.Action onFetchAndActivateSuccessful)
    {
       if(app==null)
       {
          Debug.LogError($"Do not use Firebase until it is properly initialized by calling {nameof(InitializeFirebaseAndStartGame)}.");
          return;
       }
    
       Debug.Log("Fetching data...");
       var remoteConfig = FirebaseRemoteConfig.DefaultInstance;
       remoteConfig.FetchAsync(System.TimeSpan.Zero).ContinueWithOnMainThread(
          previousTask=>
          {
             if (!previousTask.IsCompleted)
             {
             Debug.LogError($"{nameof(remoteConfig.FetchAsync)} incomplete: Status '{previousTask.Status}'");
             return;
             }
             ActivateRetrievedRemoteConfigValues(onFetchAndActivateSuccessful);
          });
    }
    
  2. بعد ذلك، أكمِل طريقة ActivateRetrievedRemoteConfigValues التي تتلقّى ردّ اتصال تم تمريره، onFetchAndActivateSuccessful. عند انتهاء عملية التفعيل، سيتم استدعاء دالة ردّ الاتصال المحدّدة:
    private void ActivateRetrievedRemoteConfigValues(System.Action onFetchAndActivateSuccessful)
    {
       var remoteConfig = FirebaseRemoteConfig.DefaultInstance;
       var info = remoteConfig.Info;
       if(info.LastFetchStatus == LastFetchStatus.Success)
       {
          remoteConfig.ActivateAsync().ContinueWithOnMainThread(
             previousTask =>
             {
             Debug.Log($"Remote data loaded and ready (last fetch time {info.FetchTime}).");
             onFetchAndActivateSuccessful();
             });
       }
    }
    

عندما يتم استدعاء ActivateRetrievedRemoteConfigValues من خلال SetRemoteConfigDefaults في سياق الإعداد، يستدعي ActivateRetrievedRemoteConfigValues نقطة البداية السابقة، InitializeCommonDataAndStartGame، لبدء اللعبة من خلال فتح القائمة الرئيسية.

6. إعداد استراتيجية تحميل في Remote Config

لاسترداد القيم وتفعيلها في وقت آخر أثناء استخدام التطبيق، عليك استدعاء هذه الدوال مرة أخرى، وإذا كانت أي عناصر قد خزّنت القيم مؤقتًا، يجب إبلاغها بإجراء تحديث. من أجل وضع استراتيجية لإعادة استرجاع قيم "الإعداد عن بُعد"، ضَع في اعتبارك الوقت الذي تحتاج فيه إلى القيم الجديدة والوقت المناسب لبدء استرجاع القيم الجديدة وتفعيلها لتجنُّب تغييرها أثناء الاستخدام.

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

عند إلقاء نظرة على نظام القوائم في Mechahamster، نجد أنّ أسهل طريقة لإضافة عمليات إعادة تحميل القوائم التي تحظر واجهة المستخدم هي استدعاؤها قبل استئناف القائمة الرئيسية (وتحديدًا عند الوصول إليها من خلال الرجوع من قائمة أخرى) وتمرير طريقة عرض واجهة المستخدم كدالة ردّ النداء onFetchAndActivateSuccessful. يمكن إجراء ذلك أيضًا في قائمة اختيار المستوى.

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

لتفعيل ذلك في التطبيق، أكمِل الطرق ذات الصلة في القائمة الرئيسية وملفات اختيار المستوى، ما سيؤدي إلى حظر عرض واجهة المستخدم إلى حين اكتمال FetchAsync وActivateAsync:

  1. افتح Assets/Hamster/Scripts/States/MainMenu.cs واستبدِل طريقة Resume الحالية بما يلي:
    public override void Resume(StateExitValue results) {
       CommonData.mainGame.SelectAndPlayMusic(CommonData.prefabs.menuMusic, true);
       CommonData.mainGame.FetchRemoteConfig(InitializeUI);
    }
    
  2. احفظ الملف.
  3. افتح Assets/Hamster/Scripts/States/BaseLevelSelect.cs، واستبدِل طريقة Resume الحالية بما يلي:
    public override void Resume(StateExitValue results) {
       CommonData.mainGame.FetchRemoteConfig(ShowUI);
    }
    
  4. احفظ الملف.

7. تصحيح أخطاء سلوكيات الجلب والتحقّق من صحتها

في هذه المرحلة، من المفيد إجراء فحص تشخيصي/تحقّق من الصحة. سيسمح لك الإجراء التالي باختبار تطبيقك يدويًا وكيفية استرجاع قيم "الإعداد عن بُعد" وتفعيلها.

سيتم طباعة المعلومات كجزء من سجلّات المحاكي أو الجهاز أو المحرّر. بالنسبة إلى نظام التشغيل iOS، يمكنك الاطّلاع على سجلّات الأجهزة والمحاكي في Xcode. في Android، يمكنك عرض السجلات من خلال تنفيذ adb logcat. إذا شغّلت الرمز في Unity من خلال النقر على "تشغيل" في المحرّر، ستظهر السجلات في علامة التبويب "وحدة التحكّم".

  1. أعِد إنشاء التطبيق وشغِّله (في "المحرّر"، باستخدام جهاز أو محاكي).
  2. بعد ظهور القائمة الرئيسية للعبة، راجِع ناتج سجلّات لعبتك الذي يجب أن يحتوي على السجلّات التي أنشأتها Debug.Log في FetchRemoteConfig وActivateRetrievedRemoteConfigValues. يجب أن تعرض هذه الرسائل "جارٍ جلب البيانات..." و "تم تحميل البيانات عن بُعد وهي جاهزة". لاحظوا الطوابع الزمنية في بداية هذه الرسائل.
  3. في اللعبة، اضغط على الترخيص.
  4. اضغط على موافق.
  5. انتظِر إلى أن تظهر القائمة الرئيسية للعبة.
  6. راجِع ناتج سجلّ اللعبة، والذي يجب أن يكون مشابهًا للنتائج في الخطوة السابقة، مع طوابع زمنية جديدة (تتطابق مع الوقت المضبوط على ساعة النظام حيث يتم تشغيل اللعبة).
  7. في اللعبة، انقر على تشغيل.
  8. اضغط على هيا نطلق العنان للإبداع.
  9. انتقِل بالكرة إلى الهدف باستخدام أسهم لوحة المفاتيح، ما سيؤدي إلى فتح قائمة "اكتمل المستوى".
  10. اضغط على المستويات.
  11. انتظِر إلى أن يتم تحميل قائمة اختيار المستوى.
  12. راجِع ناتج سجلّ اللعبة مرة أخرى. يجب أن تتطابق مع رسائل السجلّ من الخطوات السابقة، مع طوابع زمنية أحدث (تتطابق مع الوقت المضبوط على ساعة النظام حيث يتم تشغيل اللعبة).

إذا لم يظهر أيّ من هذه الإعدادات في تطبيقك، قد يكون هناك خطأ في إعداد جزء من عملية الجلب والتفعيل (أو جهازك). إذا لم يظهر السجلّ الأول، من المحتمل ألا تبدأ لعبتك. راجِع "وحدة تحكّم المحرّر" أو سجلّات الجهاز/المحاكي بحثًا عن تحذيرات وأخطاء بشأن مشروعك/بيئتك، وابحث عن حلول لها، فقد تكون المشكلة بسيطة مثل الاتصال بالإنترنت.

إذا ظهرت السجلات الأولية من تحميل القائمة، ولكن لم يظهر أحد السجلات اللاحقة، عليك التحقيق في طرق Resume في Assets/Hamster/Scripts/States/MainMenu.cs وAssets/Hamster/Scripts/States/BaseLevelSelect.cs أو إعادة تنفيذها.

8. تضمين أدوات في الرمز

بعد إعداد قيم المَعلمات داخل التطبيق في SetDefaultsAsync() وإتاحة أحدث الإصدارات باستخدام FetchAsync() وActivateAsync()، ستشير إلى هذه القيم وتستخدمها في الرمز.

بعد ضبط القيم في خلفية "الإعداد عن بُعد"، استرجِعها وفعِّلها (أو نفِّذ الإجراءين معًا)، ستتوفّر هذه القيم لتطبيقك. لاستخدام هذه القيم، استدعِ GetValue(string key)، واختَر مفتاح مَعلمة كمعلَمة. يعرض هذا الرمز ConfigValue، الذي يتضمّن سمات للوصول إلى القيمة بأنواع مختلفة متوافقة: string وbool وlong وdouble. في هذا المشروع ومعظم حالات استخدام الألعاب، يجب تحويل النوعَين الأخيرَين إلى النوعَين الأكثر تعبيرًا int وfloat. لضمان عدم تسبُّب هذه الإحالات الناجحة في حدوث مشاكل، تأكَّد من أنّ القيم الأولية التي تم ضبطها في "الإعداد عن بُعد" تندرج ضمن النطاق الصالح للأنواع التي ستستخدمها في رمز تطبيقك.

  1. استورِد ميزة "الإعداد عن بُعد" من خلال إضافة using Firebase.RemoteConfig; إلى أعلى الملفات التالية:
    • Assets/Hamster/Scripts/States/MainMenu.cs
    • Assets/Hamster/Scripts/MapObjects/AccelerationTile.cs
  2. استبدِل طريقة Start في AccelerationTile.cs بما يلي:
    private void Start() {
       var remoteConfig = FirebaseRemoteConfig.DefaultInstance;
       Acceleration = (float)remoteConfig.GetValue(AccelerationTileForceKey).DoubleValue;
    }
    
    بموجب هذا التغيير، سيتم تغيير مقدار القوة التي توفّرها لوحة التسارع إلى القيمة التي يتم تلقّيها من "الإعداد عن بُعد".
  3. عدِّل نص الدالة InitializeUI الخاصة بالفئة MainMenu.cs:
    private void InitializeUI() {
       if (menuComponent == null) {
          menuComponent = SpawnUI<Menus.MainMenuGUI>(StringConstants.PrefabMainMenu);
       }
    
       var remoteConfig = FirebaseRemoteConfig.DefaultInstance;
       var subtitleOverride = JsonUtility.FromJson<Menus.MainMenuGUI.SubtitleOverride>(
          remoteConfig.GetValue(SubtitleOverrideKey).StringValue);
       // Only sets values if all fields of the override are non-default.
       if(subtitleOverride != null && subtitleOverride.IsValidOverride())
       {
          menuComponent.MenuSubtitleText.text = subtitleOverride.text;
          menuComponent.MenuSubtitleText.fontSize = subtitleOverride.fontSize;
          menuComponent.MenuSubtitleText.color = subtitleOverride.textColor;
       }
       ShowUI();
    }
    
    في هذا المثال، تم ضبط subtitleOverride لتغيير العنوان الفرعي على شاشة القائمة الرئيسية إذا تم ضبط جميع حقوله في السحابة الإلكترونية كقيم غير القيم التلقائية للنوع.

9. ضبط قيم المَعلمات عن بُعد

بعد أن يصبح تطبيقك مجهّزًا بالكامل، يمكنك ضبط المَعلمات والقيم على خادم "الإعداد عن بُعد". في هذا الدرس العملي، سنعدِّل هذا الإعداد باستخدام وحدة تحكّم Firebase.

  1. في وحدة تحكّم Firebase، افتح مشروعك.
  2. اختَر "الإعداد عن بُعد" من القائمة لعرض لوحة بيانات "الإعداد عن بُعد".
  3. لكل مَعلمة حدّدتها في تطبيقك وأدرجتها في الجدول التالي، انقر على إضافة مَعلمة، والصِق اسم المَعلمة (المفتاح)، واختَر نوع البيانات المُدرَج في الجدول، وأوقِف استخدام القيمة التلقائية داخل التطبيق، والصِق القيمة التلقائية الجديدة:

    اسم المَعلمة (المفتاح)

    نوع البيانات

    القيمة التلقائية

    acceleration_tile_force

    الرقم

    100

    subtitle_override

    JSON

    {"text":"We overwrote the subtitle","fontSize":8,"textColor":{"r":0.0,"g":255.0,"b":0.0,"a":255.0}}

    محرّر مَعلمات &quot;الإعداد عن بُعد&quot; مع\nتعبئة acceleration_tile_force
  4. انقر على حفظ لحفظ التغييرات.
  5. انقر على نشر لنشر الإعداد الجديد وإتاحة القيم الجديدة للعبتك.
  6. شغِّل تطبيقك مرة أخرى بعد ضبط هذه المَعلمات عن بُعد ولاحظ كيف تلغي الإعدادات التلقائية الأصلية.شاشة Mechahamster الرئيسية مع تفعيل قائمة تصحيح الأخطاء

10. استخدام شروط "الإعداد عن بُعد" لعرض صيغ مختلفة

قد تحتاج إلى تخصيص تجربة التطبيق للمستخدم استنادًا إلى اللغة التي يتحدث بها أو موقعه الجغرافي أو الوقت من اليوم أو النظام الأساسي الذي يستخدمه. تمنحك شروط الإعداد عن بُعد إمكانية استخدام هذه السمات وغيرها بشكل فردي أو معًا لعرض قيم مختلفة (تُعرف باسم الصيغ) للمستخدم.

أحد الاستخدامات الشائعة للشروط هو تغيير المحتوى بين منصتَي iOS وAndroid. اتّبِع الخطوات التالية لتنفيذ شرط يعرض قيمة مختلفة لـ subtitle_override استنادًا إلى النظام الأساسي المستخدَم.

  1. افتح علامة التبويب "الإعداد عن بُعد" الخاصة بمشروعك في وحدة تحكّم Firebase.
  2. انقر على زر التعديل الخاص بـ subtitle_override.
  3. في أسفل يمين الشاشة، انقر على إضافة جديد.
  4. في القائمة المنسدلة التي تظهر، مرِّر مؤشر الماوس فوق القيمة الشرطية وانقر على إنشاء شرط جديدمحرّر مَعلمات &quot;الإعداد عن بُعد&quot;:\nخيار القيمة الشرطية.
  5. عندما يُطلب منك ذلك، أطلِق على الشرط الاسم "is iOS" إذا كنت تستهدف نظام التشغيل iOS، أو "is Android" إذا كنت تستهدف نظام التشغيل Android. إذا كنت تستهدف كلاً منهما، ما عليك سوى اختيار أحدهما هنا واستخدامه لبقية الدرس التطبيقي.استخدام مربّع الحوار &quot;تحديد شرط جديد&quot; لتحديد شرط خاص بنظام التشغيل iOS
  6. ضمن ينطبق إذا...، انقر على القائمة المنسدلة اختيار... واختَر النظام الأساسي. بعد ذلك، اختَر المنصة المناسبة.استخدام أداة التعديل Define a new condition\nلاختيار نظام التشغيل iOS
  7. انقر على إنشاء شرط لإنشاء الشرط. سيظهر مربّع الحوار "تعديل المَعلمة" من جديد، ويمكنك الآن ضبط قيمة:
    • إذا كنت تستهدف نظام التشغيل Android، اضبط القيمة على:
      {"text":"Level Up Android Version","fontSize":8,"textColor":{"r":0.0,"g":255.0,"b":0.0,"a":255.0}}
      
    • إذا كنت تستهدف نظام التشغيل iOS، اضبط القيمة على:
      {"text":"Level Up iOS Version","fontSize":8,"textColor":{"r":0.0,"g":255.0,"b":0.0,"a":255.0}}
      
  8. انقر على حفظ لحفظ التغييرات.
  9. انقر على نشر لنشر الإعداد الجديد وإتاحة القيم الجديدة للعبتك.

إذا أنشأت اللعبة وشغّلتها مرة أخرى، من المفترض أن يظهر لك العنوان الفرعي للعبة وقد تم استبداله بالصيغة الخاصة بالمنصة.

11. ضبط "الإعداد عن بُعد" لتلقّي آخر المعلومات في الوقت الفعلي

يمكن الآن لميزة "الإعداد عن بُعد" الاستماع إلى التعديلات التي يتم إجراؤها على نماذج "الإعداد عن بُعد" والتعامل معها في الوقت الفعلي. يمكن للتطبيقات الاشتراك في واجهة برمجة التطبيقات الجديدة في الوقت الفعلي لميزة "الإعداد عن بُعد" من أجل الاستماع إلى تغييرات الإعدادات والقيم المعدَّلة.

آلية العمل

للاستماع إلى التحديثات، يجب أن ينفّذ تطبيقك طريقة للاشتراك في حدث OnConfigUpdateListener. أثناء الاشتراك في واحد أو أكثر من أدوات معالجة تعديل الإعدادات، سيتم استرجاع نماذج "الإعداد عن بُعد" الجديدة تلقائيًا، وسيتم استدعاء أدوات المعالجة المشترَكة ويمكن استخدامها لتنفيذ منطق استجابة، مثل تفعيل القيم الجديدة وإتاحتها لبقية التطبيق.

تنفيذ ميزة "الإعداد عن بُعد" في الوقت الفعلي

لتوضيح طريقة عمل ذلك في اللعبة، أجرِ التغييرات التالية على الرمز البرمجي.

إنشاء معالج لتعديل الإعدادات

الخطوة الأولى لاستخدام حدث "تعديل الإعدادات" هي إنشاء طريقة يمكنها الاستماع إليه. ضَع الطريقة التالية في Assets/Hamster/Scripts/MainGame.cs:

   void ActivateValuesOnConfigUpdate( object sender, ConfigUpdateEventArgs args)
   {
      if (args.Error != RemoteConfigError.None) {
         Debug.Log($"Error occurred while listening: {args.Error}");
         return;
      }

      Debug.Log("Updated keys: " + string.Join(", ", args.UpdatedKeys));
      // Activate all fetched values and then logs.
      var remoteConfig = FirebaseRemoteConfig.DefaultInstance;
      remoteConfig.ActivateAsync().ContinueWithOnMainThread(
         task => {
            Debug.Log($"Keys from {nameof(ActivateValuesOnConfigUpdate)} activated.");
         });
   }

ستعرض هذه الطريقة قائمة بالمفاتيح المعدَّلة ورسالة نجاح في السجلّ عند تفعيل القيم الجديدة.

الاشتراك في حدث التحديث

لتفعيل ActivateValuesOnConfigUpdate عند استدعاء الحدث، عليك الاشتراك فيه. استبدِل طريقة InitializeCommonDataAndStartGame() في Assets/Hamster/Scripts/MainGame.cs بما يلي:

   void InitializeCommonDataAndStartGame()
   {
      CommonData.prefabs = FindObjectOfType<PrefabList>();
      CommonData.mainCamera = FindObjectOfType<CameraController>();
      CommonData.mainGame = this;

      Screen.orientation = ScreenOrientation.LandscapeLeft;

      musicPlayer = CommonData.mainCamera.GetComponentInChildren<AudioSource>();

      CommonData.gameWorld = FindObjectOfType<GameWorld>();

      // Set up volume settings.
      MusicVolume = PlayerPrefs.GetInt(StringConstants.MusicVolume, MaxVolumeValue);
      // Set the music to ignore the listeners volume, which is used for sound effects.
      CommonData.mainCamera.GetComponentInChildren<AudioSource>().ignoreListenerVolume = true;
      SoundFxVolume = PlayerPrefs.GetInt(StringConstants.SoundFxVolume, MaxVolumeValue);

      // Subscribes to on config update after first initial fetch and activate
      FirebaseRemoteConfig.DefaultInstance.OnConfigUpdateListener += ActivateValuesOnConfigUpdate;

      stateManager.PushState(new States.MainMenu());
   }

يؤدي السطر الجديد (الذي ينتهي بـ += ActivateValuesOnConfigUpdate;) إلى اشتراك معالج الأحداث في الحدث.

إلغاء الاشتراك عند إتلاف العنصر المالك للمعالج

لمنع أخطاء المرجع الفارغ، يجب إلغاء اشتراك الكائنات التي تتضمّن طرقًا مشترَكة في الأحداث عند إتلافها. أضِف الطريقة التالية إلى Assets/Hamster/Scripts/MainGame.cs:

   private void OnDestroy() 
   {
      FirebaseRemoteConfig.DefaultInstance.OnConfigUpdateListener -= ActivateValuesOnConfigUpdate;
   }

اختبار الوظيفة الجديدة

للتحقّق من صحة الوظيفة الجديدة، جرِّب التطبيق الذي أنشأته. يتطلّب الإجراء التالي أن تتمكّن من قراءة السجلّ وتصحيح الأخطاء باستخدام جهاز حقيقي.

تغيير acceleration_tile_force ومراقبة النتائج

بعد بدء تشغيل تطبيقك، في قسم "الإعداد عن بُعد" ضِمن وحدة تحكّم Firebase:

  1. اضغط على زر التعديل بجانب acceleration_tile_force.

dc602d4db54e50a4.png

  1. غيِّر القيمة إلى "120" واضغط على حفظ.

fcbc1df848f88009.png

  1. انقر على الزر نشر التغييرات.

3785c1e00e7a6359.png

  1. فحص السجلّ
  2. إذا ظهرت لك رسالة سجل تبدأ بعبارة "حدث خطأ أثناء الاستماع"، اقرأ بقية الرسالة وحاوِل تصحيح الأخطاء باستخدام رسالة الخطأ التي تعرضها.
  3. إذا رأيت سجلًّا يبدأ بعبارة "تم تعديل المفاتيح"، يعني ذلك أنّ تطبيقك قد تلقّى القيم المعدَّلة.
  4. إذا لم يظهر أيّ من هذين العنصرين، راجِع بقية السجلات ثم راجِع التعليمات من إنشاء معالج لتعديل الإعدادات، وأعِد الاختبار، وأعِد التحقّق من السجلات لتحديد ما إذا كان هناك أي خطأ.

12. تهانينا!

لقد استخدمت ميزة "الإعداد عن بُعد" للتحكّم في القيم داخل اللعبة عن بُعد من خلال استرجاعها في تطبيقك واستخدام الشروط لعرض صيغ مختلفة.

المواضيع التي تناولناها

  • كيفية ضبط قيم "الإعداد عن بُعد" واسترجاعها
  • كيفية إعداد رمز Unity C# لاستخدام القيم التي تم استردادها
  • كيفية تخزين القيم/الكائنات المركّبة وتفعيلها وتجاوزها كقيم JSON
  • كيفية استخدام شروط "الإعداد عن بُعد" لعرض صيغ مختلفة للقيم

الخطوات التالية

اطّلِع على أولوية قيم المَعلمات لفهم أفضل لمنطق القيم التي تحصل عليها نسخة التطبيق عند استخدام مَعلمة ذات قيم متعدّدة (بسبب الشروط أو الموقع الجغرافي).