ملخص Unity التجريبي في ميزة "هيّا نلعب" على YouTube

باستخدام هذا البرنامج، يمكنك الوصول إلى حزمة تطوير البرامج (SDK) الخاصة بميزة "هيّا نلعب" على YouTube في Unity C#. يحتوي برنامج التغليف على مكوّن إضافي .jslib وملف C# للمساعدة في تسريع عملية التطوير. يتوفّر أيضًا مشروع نموذجي يوضّح كيفية استخدامها في مشروعك.

يمكن تنزيل حِزم Unity من مستودع النماذج الخاص بميزة "هيّا نلعب".

الاستخدام

  1. تأكَّد من ضبط "النظام الأساسي" (Platform) لمشروع Unity على WebGL. يمكنك العثور على هذا الإعداد في Build Settings.
  2. يمكنك استخدام WebGLTemplate لإنشاء لعبتك على الويب، أو اتّباع قسم استخدام ملف index.html الخاص بك والتأكّد من أنّك أعددت حزمة تطوير البرامج (SDK) على الويب وبدأت استخدامها في ملف index.html.
    • يمكن العثور على WebGLTemplate في الحزمة Google-WebGLTemplate-only.unitypackage أو GoogleYTGameWrapper-with-sample.unitypackage. لإعداد هذا النموذج واستخدامه، اتّبِع الخطوات الواردة في قسم نموذج WebGL.
    • لاستخدام ملف Web وindex.html الخاصَّين بك، عليك إضافة سطرَين إلى نص برمجة إنشاء index.html في Unity. راجِع القسم استخدام ملف index.html الخاص بك لمعرفة كيفية الدمج.
  3. افتح مشروعك في Unity، ثم افتح أيًا من الحزمتَين واستورِدهما إلى مشروعك.
    • GoogleYTGameWrapper.unitypackage: يحتوي على إضافة JS لربط حزمة تطوير البرامج (SDK) الخاصة بميزة "هيّا نلعب" على YouTube وبرنامج تضمين C# للمساعدة في ربطها بمنتجك.
    • GoogleYTGameWrapper-with-sample.unitypackage: يحتوي على محتوى الملفات نفسه المتوفّر في حزمة GoogleYTGameWrapper، بالإضافة إلى نموذج يوضّح كيفية استخدام حزمة تطوير البرامج (SDK) الخاصة بألعاب "هيّا نلعب" على YouTube بلغة C#.
  4. ملاحظة مهمة: في المشهد الرئيسي، أنشئ عنصرًا جديدًا في اللعبة وسمِّه YTGameWrapper. يُستخدَم عنصر اللعبة هذا للتواصل مع جسر JavaScript.
  5. ملاحظة مهمة: أضِف رمز YTGameWrapper.cs الذي تم استيراده كأحد مكونات البرنامج النصي إلى عنصر YTGameWrapper GameObject.
  6. إذا كان مشروعك يتضمّن مشاهد متعددة، احرص على إضافة DontDestroyOnLoad إلى نص YTGameWrapper.cs البرمجي (ملاحظة: تتضمّن الإصدارات الجديدة من النص البرمجي مفتاح تبديل DontDestroyOnSceneChange يكون مفعّلاً تلقائيًا). سيضمن ذلك بقاء النص البرمجي وGameObject طوال فترة اللعب.

    GameObject.DontDestroyOnLoad(this.gameObject);
    
  7. يتم استخدام المكوّن YTGameWrapper.cs وGameObject YTGameWrapper للربط بحزمة تطوير البرامج (SDK) الخاصة بـ "هيّا نلعب على YouTube". استخدِم هذه الأجهزة للاتصال بتطبيق YouTube. إما باستخدام Script للعثور على العنصر والمكوّن أو إضافة هذه العناصر يدويًا إلى رمز اللعبة من خلال Unity Editor.

  8. تأكَّد من اتّباع المتطلبات الفنية لمشروعك.

استخدام ملف index.html الخاص بك

إذا لم تستخدِم مثال index.html المقدَّم، عليك إضافة سطرَين من الرمز إلى برنامج إنشاء index.html في Unity.

أولاً، أضِف هذا السطر في المكان نفسه الذي يضبط فيه مشروعك المتغيرات الخاصة بحاوية Unity ولوحة العرض وما إلى ذلك.

    var container = document.querySelector("#unity-container");
    var canvas = document.querySelector("#unity-canvas");

    var unityGameInstance = null; // <-- Add this line >

    ...

ثانيًا، أضِف هذا السطر داخل الدالة createUnityInstance.

    createUnityInstance(canvas, config, (progress) => {
        progressBarFull.style.width = 100 * progress + "%";
    }).then((unityInstance) => {

        unityGameInstance = unityInstance; // <-- Add this line >

    ...

أمثلة

يتضمّن هذا القسم بعض الأمثلة على كيفية استخدام برنامج تضمين C#، وهو ليس القائمة الكاملة لواجهات برمجة التطبيقات المتاحة. للاطّلاع على القائمة الكاملة لواجهات برمجة التطبيقات المتاحة، يُرجى الرجوع إلى حزمة تطوير البرامج (SDK) الخاصة بميزة "هيّا نلعب على YouTube".

sendScore

يعرض هذا المثال عملية تنفيذ sendScore(int points) في C#:

...
using YTGameSDK;
...

public YTGameWrapper ytGameWrapper;
public int battleScore = 0;

...

// Update the total score and send this to the YouTube Game Wrapper.
public void UpdateScores(int scoreAmt)
{
    battleScore += scoreAmt;
    // ytGameWrapper should be a reference to your YTGameWrapper component.
    ytGameWrapper.SendGameScore(battleScore);
}

onPause

في ما يلي مثال على كيفية استماع إحدى الألعاب إلى أحداث Pause واردة من "الألعاب على YouTube"، وذلك لإيقاف المحرّك مؤقتًا عند الحاجة:

...
using YTGameSDK;
...

public YTGameWrapper ytGameWrapper;
public bool gameIsPaused = false;

...
void Start()
{
    // Sets the OnPause callback with the YT Playables SDK
    ytGameWrapper.SetOnPauseCallback(PauseTheGameCallback);
}

// Pause game callback, will pause the game when called.
public void PauseTheGameCallback()
{
    gameIsPaused = true;
}

saveData

في ما يلي مثال على كيفية استخدام saveData وإرساله إلى حزمة تطوير البرامج (SDK) للألعاب على YouTube:

...
using YTGameSDK;
...

public YTGameWrapper ytGameWrapper;

...

// Saves the current score of the game and converts it to a JSON format.
public void SaveScore(int scoreAmt)
{
    SaveGameData("{\"BestScore\": \"" + scoreAmt.ToString() + "\"}");
}

public void SaveGameData(string saveString)
{
    if (string.IsNullOrEmpty(saveString)) return;

    // Sends save data to the YT Playables SDK
    ytGameWrapper.SendGameSaveData(saveString);
}

loadData

في ما يلي مثال على كيفية استخدام loadData وإرساله إلى حزمة تطوير البرامج (SDK) للألعاب على YouTube:

...
using UnityEngine;
using YTGameSDK;
...

[Serializable]
public class LoadedScores
{
    public int BestScore;
    public float BestTime;
}

public YTGameWrapper ytGameWrapper;

...

void Start()
{
    ytGameWrapper.LoadGameSaveData(LoadSaveGameDataReturned);
}

public void LoadSaveGameDataReturned(string data)
{
    if (!string.IsNullOrEmpty(data))
    {
        LoadedScores loadedScores = JsonUtility.FromJson<LoadedScores>(data);
        Debug.Log("LoadSaveGameDataReturned > Score <" + loadedScores.BestScore.ToString()
                  +   "> Time <" + loadedScores.BestTime.ToString("0.00"));
    }
}

requestInterstitialAd

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

...
using YTGameSDK;
...

public YTGameWrapper ytGameWrapper;

...

// At the end of a round send a request to show an interstitial Ad, if one is
//  available an Ad will be shown and Pause Game Callback should be called.

// EXAMPLE: send and forget
public void RequestInterstitialAd()
{
    ytGameWrapper.RequestInterstitialAd();
}

// EXAMPLE: send and react to if an Ad was shown
public void RequestInterstitialAd()
{
    int status = ytGameWrapper.RequestInterstitialAd();
    if (status == 0)
    {
        // Ad request was successful, do some action.
    }
}

requestRewardedAd

هذا مثال على كيفية استخدام requestRewardedAd. يتم استخدام هذا الرمز عندما يختار المستخدم مشاهدة "إعلان مقابل مكافأة" مقابل الحصول على مكافأة في لعبتك. إذا كان الإعلان متاحًا، سيتم عرضه للمستخدم.

...
using YTGameSDK;
...

public YTGameWrapper ytGameWrapper;

...

public void RequestRewardedAd()
{
    // Register callback for Rewarded Ads. If an Ad is available one will be
    //  shown. Pause Game Callback should be called. Any ID is fine as long as
    //  its identifyable for your game.
    ytGameWrapper.RequestRewardedAd("my-reward-ad-id-123", (rewardEarned) => {
        if (rewardEarned) {
            // Rewarded Ad is earned, reward the user.
        } else {
            // Rewarded Ad not earned, take the appropriate action
        }
    });
}

كيفية استخدام نموذج WebGL على YouTube

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

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

نموذج WebGL

  1. اتّبِع تعليمات حزمة Unity أعلاه لإجراء عملية الإعداد الأوّلي. احرص على استخدام Google-WebGLTemplate-only.unitypackage أو GoogleYTGameWrapper-with-sample.unitypackage واستيراد جميع الملفات ضمن المجلد WebGLTemplates/YTGameWrapperTemplate/.
    • ملاحظة: إذا لم يسبق لك استيراد YTGameWrapper.cs وUnityYTGameSDKLib.jslib، عليك استيرادهما أيضًا.
  2. اضبط نموذج WebGL على استخدام YTGameWrapperTemplate. يمكنك العثور على هذا الإعداد في Edit -> Project settings -> Player -> علامة التبويب WebGL -> القسم Resolution and Presentation.
    • ملاحظة: يتم ضبط العرض والارتفاع التلقائيَين للوحة العرض على% 100 في النموذج، لذا لن تؤدي إعدادات Unity هذه إلى تعديل أي شيء.
  3. تأكَّد من ضبط Compression Format على "غير مفعَّل". يمكنك العثور على هذا الإعداد في علامة التبويب Project settings -> Player -> WebGL -> القسم Publishing Settings.
  4. أنشئ WebGL في النافذة Build Settings، ثم انتقِل إلى الخطوة 7 أو 5 استنادًا إلى احتياجات مشاريعك.
  5. اتّبِع الخطوتَين 5 و6 فقط في حال استخدام الضغط: بعد إنشاء مشروعك، انتقِل إلى موقع مجلد التصميم وافتح المجلد Build. ابحث عن ملفات .wasm أو .data الخاصة بمشاريعك التي تحتاج إلى ضغط لتناسب حدود حجم الملف الفردي، ثم اضغط هذه الملفات. احرص على حذف ملفات .wasm أو .data الأصلية التي تم ضغطها لأنّك سترسل ملفات *.wasm.zip و*.data.zip بدلاً منها.
    • ملاحظة: إذا كنت تستخدم جهاز Mac، يمكنك النقر بزر الماوس الأيمن على الملف واختيار "ضغط *"، أما على جهاز الكمبيوتر، فيمكنك النقر بزر الماوس الأيمن على الملف واختيار "الضغط إلى ملف ZIP".
  6. يجب اتّباع هذه الخطوة فقط إذا نفّذت الخطوة 5: عدِّل ملف index.html الذي تم إنشاؤه من YTGameWrapperTemplate لتحميل الملفات المضغوطة وفك ضغطها.
    • بالقرب من نهاية ملفات index.html، ستجد Path 1، لذا عليك إضافة تعليق إلى السطر التالي InitUnitySection();.
    • بالقرب من نهاية ملفات index.html، ستجد Path 2، لذا عليك إضافة تعليق إلى السطر التالي loadResources(InitUnitySection);.
  7. عند إرسال مشروعك للحصول على شهادة الاعتماد، عليك إرسال جميع الملفات التي تم إنشاؤها من Unity إلى موقع الإنشاء من الخطوة 4. وإذا تم اتباع الخطوتين 5 و6، يجب تضمين هذه الملفات أيضًا.

ترقية النماذج المتوفّرة لاستخدام Universal Render Pipeline (URP)

من بين أحدث التحسينات التي تم إدخالها على الإصدارات الأحدث من Unity أنّها تستخدم Universal Render Pipeline (URP). لترقية العيّنة حتى يتم عرض كل شيء بشكل صحيح.

  1. ابدأ باستيراد حزمة GoogleYTGameWrapper-with-sample.unitypackage إلى مشروع جديد أو حالي.
  2. انتقِل إلى نافذة Render Pipeline Converter: Window -> Rendering -> Render Pipeline Converter.
  3. اختَر Rendering Settings وMaterial Upgrade وReadonly Material Converter.
  4. بعد ذلك، اختَر Initialize and Convert وانتظِر إلى حين انتهاء هذه العملية، وسيكون النموذج جاهزًا للاستخدام في URP.

كيفية تقسيم مواد العرض في مشروع Unity (التحميل الكسول)

من المشاكل الرئيسية التي أشار إليها المطوّرون عند استخدام Unity هو الالتزام بمتطلبات حجم الملف الفردي ومتطلبات حجم الحِزمة الإجمالي.

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

للمساعدة في تحميل مواد العرض بشكل صحيح، توفّر Unity عددًا من الطرق لتقسيم مواد العرض، مع التأكّد من أنّ مجموعات مواد العرض الفردية لا تتجاوز حدود الحجم وأنّك تحمّل المحتوى بمرور الوقت. ننصحك باستخدام Addressables أو Asset Bundles.

Addressables

تتيح لك Addressables تحديد الملفات المختلفة التي يجب تحميلها معًا، وسيتولّى Unity معظم عملية التجميع نيابةً عنك. يوفّر Unity أيضًا بعض الأدوات لإدارة أحجام الملفات والمساعدة في التأكّد من عدم تكرار مواد العرض.

لاستخدام Addressables، عليك استيراد حزمة Addressables من خلال Package Manager في Unity، ثم تصنيف مواد العرض في Addressable Groups. يمكنك الاطّلاع على مزيد من التفاصيل من خلال مستندات Unity.

حِزم مواد العرض

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

يمكنك الاطّلاع على مرجع واجهة برمجة التطبيقات الكامل لـ YT Playables.