دمج مواد العرض (Unity)

عند دمج ميزة "إرسال مواد العرض"، يمكن لألعاب Unity الوصول إلى حِزم مواد العرض باستخدام مواد العرض القابلة للإضافة أو حزمة مواد العرض. تمثّل العناوين القابلة للمعالجة الحلّ الأحدث والموصى به لعرض مواد العرض في الألعاب التي تم إنشاؤها باستخدام Unity 2019.4 أو إصدار أحدث، في حين أنّ AssetBundle توفّر حِزم مواد العرض في Unity 2017.4 و2018.4.

أهداف الوحدة

في الألعاب التي تم إنشاؤها باستخدام Unity 2019.4 أو إصدار أحدث، يجب استخدام عنصر Addressables لتسليم مواد العرض على Android. توفّر Unity واجهة برمجة تطبيقات Play Asset Delivery (PAD) للتعامل مع حِزم مواد العرض في نظام التشغيل Android باستخدام ميزة Addressables. للحصول على معلومات حول استخدام "العنوان"، راجع ما يلي:

استخدام ملفات AssetBundle

يمكن للألعاب التي تم إنشاؤها باستخدام Unity 2017.4 و2018.4 استخدام ملفات AssetBundle لعرض المواد على Android. تحتوي ملفات Unity AssetBundle على أصول متسلسلة يمكن تحميلها بواسطة محرّك Unity أثناء تشغيل التطبيق. هذه الملفات خاصة بنظام التشغيل (على سبيل المثال، مصممة لنظام التشغيل Android) ويمكن استخدامها مع حِزم مواد العرض. وغالبًا ما يتم حزم ملف AssetBundle واحد في حزمة مواد عرض واحدة، إلى جانب اسم الحزمة نفسها التي تحمل اسم AssetBundle. إذا كنت تريد المزيد من المرونة في إنشاء حزمة مواد عرض، يمكنك ضبط حزمة مواد العرض باستخدام واجهة برمجة التطبيقات.

في وقت التشغيل، استخدِم الفئة عرض المواد في Play لبرنامج Unity لاسترداد حزمة AssetBundle في حزمة مواد عرض.

المتطلّبات الأساسية

  1. يمكنك تنزيل أحدث إصدار من المكوّن الإضافي Play Asset Delivery Unity الإضافي من حزم Google لبرنامج Unity.

  2. أنشِئ حزم مواد العرض بتنسيق Unity.

إعداد AssetBundle باستخدام واجهة المستخدم

  1. ضبط كل حزمة AssetBundle في حزمة مواد عرض:

    1. اختَر Google > مجموعة حزمات تطبيق Android > إعدادات عرض مواد العرض.
    2. لتحديد المجلدات التي تحتوي مباشرةً على ملفات AssetBundle، انقر على إضافة مجلد.

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

  3. اختَر Google > إنشاء مجموعة حزمات تطبيق Android لإنشاء حِزمة التطبيق.

  4. (اختياري) يمكنك ضبط حزمة تطبيقك بحيث تتوافق مع تنسيقات مختلفة لضغط الزخرفة.

إعداد حِزم مواد العرض باستخدام واجهة برمجة التطبيقات

يمكنك ضبط تسليم مواد العرض من خلال النصوص البرمجية للمحرّر التي يمكن تشغيلها كجزء من نظام تصميم آلي.

استخدِم الفئة AssetPackConfig لتحديد مواد العرض المطلوب تضمينها في إصدار "مجموعة حزمات تطبيق Android"، بالإضافة إلى وضع عرض مواد العرض. ليس بالضرورة أن تحتوي حِزم مواد العرض هذه على AssetBundle.

public void ConfigureAssetPacks {
   // Creates an AssetPackConfig with a single asset pack, named
   // examplePackName, containing all the files in path/to/exampleFolder.
   var assetPackConfig = new AssetPackConfig();
   assetPackConfig.AddAssetsFolder("examplePackName",
                                   "path/to/exampleFolder",
                                   AssetPackDeliveryMode.OnDemand);

   // Configures the build system to use the newly created assetPackConfig when
   // calling Google > Build and Run or Google > Build Android App Bundle.
   AssetPackConfigSerializer.SaveConfig(assetPackConfig);

   // Alternatively, use BundleTool.BuildBundle to build an App Bundle from script.
   BuildBundle(new buildPlayerOptions(), assetPackConfig);
}

يمكنك أيضًا استخدام الطريقة BuildBundle الثابتة في الفئة Bundletool لإنشاء "مجموعة حزمات تطبيق Android" تتضمّن حِزم مواد عرض، وذلك وفقًا للفقرة BuildPlayerOptions وAssetPackConfig.

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

الدمج مع واجهة برمجة التطبيقات Play Asset Delivery Unity API

توفّر Play Asset Delivery Unity API الوظائف لطلب حِزم مواد العرض وإدارة عمليات التنزيل والوصول إلى مواد العرض. احرص أولاً على إضافة المكوّن الإضافي Unity إلى مشروعك.

تعتمد الدوال التي تستخدمها في واجهة برمجة التطبيقات على الطريقة التي أنشأت بها حِزم مواد العرض.

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

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

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

مخطط تفصيلي لحِزم مواد العرض لواجهة برمجة التطبيقات

الشكل 1. رسم بياني للتدفق للوصول إلى حِزم مواد العرض

استرداد حزمة مواد عرض

استورِد مكتبة مواد العرض في Play واطلب طريقة RetrieveAssetPackAsync() لتنزيل حزمة مواد العرض إذا لم يكن أحدث إصدار منها متوفّرًا على القرص.

using Google.Play.AssetDelivery;

// After download, the assets and/or AssetBundles contained in the asset pack
// are not loaded into memory.
PlayAssetPackRequest request = PlayAssetDelivery.RetrieveAssetPackAsync(assetPackName);

التسليم في وقت التثبيت

تتوفّر حزمة مواد العرض التي تم ضبطها على أنّها install-time على الفور عند إطلاق التطبيق، ولكن عليك تحميل مواد العرض الخاصة بها في الذاكرة. راجِع تحميل مواد العرض في الذاكرة.

متابعة سريعة وتسليم عند الطلب

تنطبق هذه الأقسام على حِزمتَي مواد عرض fast-follow وon-demand.

فحص الحالة

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

تتبُّع عملية التنزيل

استعلام عن كائن PlayAssetPackRequest لمراقبة حالة الطلب:

// Download progress of request, between 0.0f and 1.0f. The value will always be
// 1.0 for assets delivered as install-time.
// NOTE: A value of 1.0 does not mean that the request has completed, only that
// the DOWNLOADING stage is finished.
float progress = request.DownloadProgress;

// Returns the status of the retrieval request.
// If the request completed successfully, this value should be AssetDeliveryStatus.Available.
// If an error occurred, this value should be AssetDeliveryStatus.Failed.

AssetDelivery status = request.Status;
switch(status) {
    case AssetDeliveryStatus.Pending:
        // Asset pack download is pending - N/A for install-time assets.
    case AssetDeliveryStatus.Retrieving:
        // Asset pack is being downloaded and transferred to app storage.
        // N/A for install-time assets.
    case AssetDeliveryStatus.Available:
        // Asset pack is downloaded on disk but NOT loaded into memory.
        // For PlayAssetPackRequest(), this indicates that the request is complete.
    case AssetDeliveryStatus.Failed:
        // Asset pack retrieval failed.
    case AssetDeliveryStatus.WaitingForWifi:
        // Asset pack retrieval paused until either the device connects via Wi-Fi,
        // or the user accepts the PlayAssetDelivery.ShowConfirmationDialog dialog.
    case AssetDeliveryStatus.RequiresUserConfirmation:
        // Asset pack retrieval paused until the user accepts the
        // PlayAssetDelivery.ShowConfirmationDialog dialog.
    default:
        break;
}

// Returns true if status is AssetDeliveryStatus.Available or AssetDeliveryStatus.Failed.
bool done = request.IsDone;

// If AssetDeliveryStatus.Failed, find more info about the error.
AssetDeliveryErrorCode error = request.Error;

عمليات تنزيل كبيرة الحجم

ويمكن تنزيل حِزم مواد العرض التي يزيد حجمها عن 200 ميغابايت تلقائيًا، ولكن فقط في حال اتصال الجهاز بشبكة Wi-Fi. وإذا لم يكن المستخدم متصلاً بشبكة Wi-Fi، يتم ضبط حالة PlayAssetPackRequest على AssetDeliveryStatus.WaitingForWifi ويتم إيقاف التنزيل مؤقتًا. في هذه الحالة، عليك إما الانتظار حتى يتصل الجهاز بشبكة Wi-Fi، أو استئناف عملية التنزيل، أو الطلب من المستخدم الموافقة على تنزيل الحزمة عبر اتصال شبكة جوّال.

تأكيد المستخدم المطلوب

وإذا كانت الحزمة بالحالة AssetDeliveryStatus.RequiresUserConfirmation، لن تتم مواصلة التنزيل حتى يوافق المستخدم على مربّع الحوار الذي يظهر مع PlayAssetDelivery.ShowConfirmationDialog(). يمكن أن تظهر هذه الحالة إذا لم يتم التعرّف على التطبيق من خلال Play. يُرجى العِلم بأنّ طلب الرمز PlayAssetDelivery.ShowConfirmationDialog() في هذه الحالة يؤدي إلى تحديث التطبيق. بعد التعديل، اطلب مواد العرض مرة أخرى.

if(request.Status == AssetDeliveryStatus.RequiresUserConfirmation
   || request.Status == AssetDeliveryStatus.WaitingForWifi) {
    var userConfirmationOperation = PlayAssetDelivery.ShowConfirmationDialog();
    yield return userConfirmationOperation;

    switch(userConfirmationOperation.GetResult()) {
        case ConfirmationDialogResult.Unknown:
            // userConfirmationOperation finished with an error. Something went
            // wrong when displaying the prompt to the user, and they weren't
            // able to interact with the dialog.
        case ConfirmationDialogResult.Accepted:
            // User accepted the confirmation dialog--an update will start.
        case ConfirmationDialogResult.Declined:
            // User canceled or declined the dialog. It can be shown again.
        default:
            break;
    }
}

إلغاء طلب (عند الطلب فقط)

إذا كنت بحاجة إلى إلغاء الطلب قبل تنزيل حِزم مواد العرض، عليك استدعاء الإجراء AttemptCancel() في الكائن PlayAssetPackRequest:

// Will only attempt if the status is Pending, Retrieving, or Available; otherwise
// it will be a no-op.
request.AttemptCancel();

// Check to see if the request was successful by checking if the error code is Canceled.
if(request.Error == AssetDeliveryErrorCode.Canceled) {
    // Request was successfully canceled.
}

تحميل مواد العرض في الذاكرة

بعد اكتمال الطلب، يمكنك استخدام إحدى الدوال التالية لتحميل مواد العرض إلى الذاكرة:

طلب حِزم مواد العرض بشكل غير متزامن

في معظم الحالات، عليك استخدام الكوروتينات لطلب حِزم مواد العرض بشكل غير متزامن ومراقبة مستوى التقدّم، كما هو موضّح في ما يلي:

private IEnumerator LoadAssetPackCoroutine(string assetPackName) {

    PlayAssetPackRequest request =
        PlayAssetDelivery.RetrieveAssetPackAsync(assetPackName);

    while (!request.IsDone) {
        if(request.Status == AssetDeliveryStatus.WaitingForWifi) {
            var userConfirmationOperation = PlayAssetDelivery.ShowConfirmationDialog();

            // Wait for confirmation dialog action.
            yield return userConfirmationOperation;

            if((userConfirmationOperation.Error != AssetDeliveryErrorCode.NoError) ||
               (userConfirmationOperation.GetResult() != ConfirmationDialogResult.Accepted)) {
                // The user did not accept the confirmation. Handle as needed.
            }

            // Wait for Wi-Fi connection OR confirmation dialog acceptance before moving on.
            yield return new WaitUntil(() => request.Status != AssetDeliveryStatus.WaitingForWifi);
        }

        // Use request.DownloadProgress to track download progress.
        // Use request.Status to track the status of request.

        yield return null;
    }

    if (request.Error != AssetDeliveryErrorCode.NoError) {
        // There was an error retrieving the pack. For error codes NetworkError
        // and InsufficientStorage, you may prompt the user to check their
        // connection settings or check their storage space, respectively, then
        // try again.
        yield return null;
    }

    // Request was successful. Load the asset pack into memory.
    AssetBundleCreateRequest assetBundleCreateRequest = request.LoadAssetBundleAsync(path/to/exampleBundle);
    yield return assetBundleCreateRequest;
    AssetBundle assetBundle = assetBundleCreateRequest.assetBundle;

لمزيد من المعلومات حول معالجة الأخطاء، راجِع قائمة رموز الأخطاء.

طرق أخرى لواجهة Play Core API

في ما يلي بعض طرق واجهة برمجة التطبيقات الإضافية التي قد تريد استخدامها في تطبيقك.

استرداد حِزم مواد عرض متعددة

لاسترداد حِزم مواد عرض متعددة في آنٍ واحد، استخدم الدالة التالية:

// assetPackNames is an array of strings corresponding to asset packs.
PlayAssetPackBatchRequest batchRequest = PlayAssetDelivery.RetrieveAssetPackBatchAsync(<IListstring> assetPackNames);

تتبَّع حالات كل طلب من خلال فحص Dictionary حالة:

// Dictionary of AssetPackStates, with the asset pack name as the key.
Dictionary<string, PlayAssetPackRequest> requests = batchRequest.Requests;

// Returns true if all requests are complete.
bool requestComplete = batchRequest.IsDone;

التحقّق من حجم عمليات التنزيل

يمكنك التحقق من حجم حزمة مواد العرض عن طريق إجراء اتصال غير متزامن مع Google Play وضبط طريقة لمعاودة الاتصال عند اكتمال العملية:

public IEnumerator GetDownloadSize() {
   PlayAsyncOperation<long> getSizeOperation =
   PlayAssetDelivery.GetDownloadSize(assetPackName);

   yield return getSizeOperation;
   if(operation.Error != AssetDeliveryErrorCode.NoError) {
       // Error while retrieving download size.
    } else {
        // Download size is given in bytes.
        long downloadSize = operation.GetResult();
    }
}

إزالة AssetBundle

يمكنك إزالة حِزم مواد العرض التي تتم متابعتها السريعة وحِزم مواد العرض عند الطلب غير المحمّلة حاليًا في الذاكرة. يمكنك إجراء الاستدعاء غير المتزامن التالي وتعيين طريقة رد الاتصال عند اكتمالها:

PlayAsyncOperation<string> removeOperation = PlayAssetDelivery.RemoveAssetPack(assetBundleName);

removeOperation.Completed += (operation) =>
            {
                if(operation.Error != AssetDeliveryErrorCode.NoError) {
                    // Error while attempting to remove AssetBundles.
                } else {
                    // Files were deleted OR files did not exist to begin with.
                }
            };

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

يمكنك اختبار تسليم مواد العرض محليًا ومن Google Play.