ادغام کردن ارائه دارایی (Unity)

بازی‌های Unity هنگام ادغام ارائه دارایی می‌توانند بااستفاده از «نشانی‌پذیرها» یا «بسته‌های دارایی» به بسته‌های دارایی دسترسی پیدا کنند. «نشانی‌پذیرها» راهکار جدیدتر و توصیه‌شده‌تری برای ارائه دارایی در بازی‌های ساخته‌شده با Unity 2019.4 یا بالاتر است، درحالی‌که «دسته‌های دارایی» از بسته‌های دارایی در Unity 2017.4 و 2018.4 پشتیبانی می‌کنند.

Unity Addressables

بازی‌های ساخته‌شده با Unity 2019.4 یا بالاتر باید از Addressables برای ارائه دارایی در Android استفاده کنند. ‫Unity یک Play Asset Delivery (PAD) API برای مدیریت بسته‌های دارایی Android بااستفاده از Addressables ارائه می‌دهد. برای کسب اطلاعات درباره استفاده از «آدرس‌دارها»، به موارد زیر مراجعه کنید:

استفاده از فایل‌های AssetBundle

بازی‌های ساخته‌شده با Unity 2017.4 و 2018.4 می‌توانند از فایل‌های AssetBundle برای ارائه دارایی در Android استفاده کنند. فایل‌های Unity AssetBundle حاوی دارایی‌های سریالی‌شده‌ای هستند که موتور Unity می‌تواند آن‌ها را درحین اجرای برنامه بار کند. این فایل‌ها مختص پلاتفرم هستند (برای مثال، برای Android ساخته شده‌اند) و می‌توانند در ترکیب با بسته‌های دارایی استفاده شوند. معمولاً، یک فایل AssetBundle در یک بسته دارایی واحد بسته‌بندی می‌شود، و بسته از همان نام AssetBundle استفاده می‌کند. اگر می‌خواهید در ایجاد بسته دارایی انعطاف‌پذیری بیشتری داشته باشید، بسته دارایی را بااستفاده از API پیکربندی کنید.

در زمان اجرا، از کلاس ارائه دارایی‌های Play برای Unity برای بازیابی AssetBundle بسته‌بندی‌شده در بسته دارایی استفاده کنید.

پیش‌نیازها

  1. محیط توسعه خود را راه‌اندازی کنید:

OpenUPM-CLI

اگر OpenUPM CLI نصب شده باشد، می‌توانید ثبت OpenUPM را با دستور زیر نصب کنید:

openupm add com.google.play.assetdelivery

OpenUPM

  1. با انتخاب گزینه منو Unity، تنظیمات مدیر بسته را باز کنید ویرایش > تنظیمات پروژه > مدیر بسته.

  2. ‫OpenUPM را به‌عنوان ثبت‌کننده محدود به پنجره «مدیر بسته» اضافه کنید:

    Name: package.openupm.com
    URL: https://package.openupm.com
    Scopes: com.google.external-dependency-manager
      com.google.play.common
      com.google.play.core
      com.google.play.assetdelivery
      com.google.android.appbundle
    
  3. با انتخاب گزینه منو Unity Window > Package Manager (پنجره > مدیر بسته)، منو مدیر بسته را باز کنید.

  4. منوِ کرکره‌ای محدوده مدیر را روی ثبت‌های من تنظیم کنید.

  5. بسته افزایه تمامیت Google Play برای Unity را از فهرست بسته انتخاب کنید و نصب را فشار دهید.

وارد کردن از GitHub

  1. آخرین .unitypackage نسخه را از GitHub بارگیری کنید.

  2. فایل .unitypackage را با انتخاب گزینه منو Unity دارایی‌ها > وارد کردن بسته > بسته سفارشی و وارد کردن همه موارد وارد کنید.

  1. ایجاد AssetBundles در Unity.

پیکربندی AssetBundles بااستفاده از UI

  1. هر AssetBundle را در بسته دارایی پیکربندی کنید:

    1. Google > دسته برنامه Android > تنظیمات توزیع دارایی را انتخاب کنید.
    2. برای انتخاب پوشه‌هایی که مستقیماً حاوی فایل‌های AssetBundle هستند، روی افزودن پوشه کلیک کنید.

  2. برای هر دسته، حالت ارائه را به زمان نصب، دنبال کردن سریع، یا درصورت تقاضا تغییر دهید. خطاها یا وابستگی‌ها را حل‌وفصل کنید و پنجره را ببندید.

  3. برای ساختن دسته برنامه، Google > ساختن دسته برنامه Android را انتخاب کنید.

  4. (اختیاری) دسته برنامه را پیکربندی کنید تا از قالب‌های فشرده‌سازی بافت مختلف پشتیبانی کند.

پیکربندی بسته‌های دارایی بااستفاده از API

می‌توانید توزیع دارایی را ازطریق دستورگان‌های ویرایشگر که می‌توانند به‌عنوان بخشی از سیستم ساخت خودکار اجرا شوند پیکربندی کنید.

از کلاس AssetPackConfig برای تعریف اینکه کدام دارایی‌ها در ساخت Android App Bundle گنجانده شود، و همچنین حالت ارائه دارایی‌ها استفاده کنید. این بسته‌های دارایی نیازی به داشتن «بسته دارایی» ندارند.

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 روش static در کلاس Bundletool برای تولید Android App Bundle با بسته‌های دارایی استفاده کنید، با درنظر گرفتن BuildPlayerOptions و AssetPackConfig.

برای آموزش گام‌به‌گام، به استفاده از «ارائه دارایی‌های Play» در بازی‌های Unity Codelab مراجعه کنید.

ادغام با Play Asset Delivery Unity API

میانای برنامه‌سازی کاربردی Play Asset Delivery Unity کارکردهای درخواست بسته‌های دارایی، مدیریت بارگیری‌ها، و دسترسی به دارایی‌ها را فراهم می‌کند. ابتدا مطمئن شوید که افزایه Unity را به پروژه خود اضافه کرده‌اید.

کارکردهایی که در «میانای برنامه‌سازی کاربردی» استفاده می‌کنید به نحوه ایجاد بسته‌های دارایی بستگی دارد.

اگر بسته‌های دارایی را بااستفاده از واسط کاربر افزایه ایجاد کرده‌اید، بسته‌های دارایی پیکربندی‌شده با افزایه را انتخاب کنید.

اگر بسته‌های دارایی را بااستفاده از API (یا رابط کاربری افزایه) ایجاد کرده‌اید، بسته‌های دارایی پیکربندی‌شده با API را انتخاب کنید.

شما براساس نوع توزیع بسته دارایی که می‌خواهید به آن دسترسی داشته باشید، API را پیاده‌سازی می‌کنید. این مراحل در جریان‌نمای زیر نشان داده شده است.

نمودار جریان بسته دارایی برای افزایه

شکل ۱. رَوَندنما برای دسترسی به بسته‌های دارایی

بازیابی AssetBundles

کتابخانه «ارائه دارایی‌های Play» را وارد کنید و روش RetrieveAssetBundleAsync() را برای بازیابی کردن AssetBundle فراخوانی کنید.

using Google.Play.AssetDelivery;

// Loads the AssetBundle from disk, downloading the asset pack containing it if necessary.
PlayAssetBundleRequest bundleRequest = PlayAssetDelivery.RetrieveAssetBundleAsync(asset-bundle-name);

تحویل در زمان نصب

بسته‌های دارایی پیکربندی‌شده به‌عنوان install-time بلافاصله پس‌از راه‌اندازی برنامه دردسترس قرار می‌گیرند. برای بار کردن صحنه از AssetBundle می‌توانید از موارد زیر استفاده کنید:

AssetBundle assetBundle = bundleRequest.AssetBundle;

// You may choose to load scenes from the AssetBundle. For example:
string[] scenePaths = assetBundle.GetAllScenePaths();
SceneManager.LoadScene(scenePaths[path-index]);

ارائه سریع و درخواستی

این بخش‌ها برای fast-follow و بسته‌های دارایی on-demand اعمال می‌شود.

بررسی وضعیت

هر بسته دارایی در پوشه‌ای جداگانه در فضای ذخیره‌سازی داخلی برنامه ذخیره می‌شود. از روش isDownloaded() برای تعیین اینکه آیا بسته دارایی قبلاً بارگیری شده است یا نه استفاده کنید.

بر بارگیری نظارت کنید

برای پایش وضعیت درخواست، PlayAssetBundleRequest شیء را پُرسمان کنید:

// 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 will only signify the download is complete. It will still need to be loaded.
float progress = bundleRequest.DownloadProgress;

// Returns true if:
//   * it had either completed the download, installing, and loading of the AssetBundle,
//   * OR if it has encountered an error.
bool done = bundleRequest.IsDone;

// Returns status of retrieval request.
AssetDeliveryStatus status = bundleRequest.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.Loading:
        // Asset pack is being loaded.
    case AssetDeliveryStatus.Loaded:
        // Asset pack has finished loading, assets can now be loaded.
        // For PlayAssetBundleRequest(), this indicates that the request is complete.
    case AssetDeliveryStatus.Failed:
        // Asset pack retrieval has 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;
}

بارگیری‌های بزرگ

بسته‌های دارایی بزرگ‌تر از ۲۰۰ مگابایت می‌توانند به‌طور خودکار بارگیری شوند، اما فقط در Wi-Fi. اگر کاربر از Wi-Fi استفاده نمی‌کند، وضعیت PlayAssetBundleRequest به 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;
    }
}

لغو کردن درخواست (فقط درصورت تقاضا)

اگر لازم است درخواست را قبل‌از بار شدن AssetBundle در حافظه لغو کنید، روش AttemptCancel() را در PlayAssetBundleRequest فراخوانی کنید:

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

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

درخواست بسته‌های دارایی به‌صورت ناهمزمان

در بیشتر موارد، باید از روال‌های همکار برای درخواست ناهمزمان بسته‌های دارایی و نظارت بر پیشرفت استفاده کنید، همان‌طور که در زیر نشان داده شده است:

private IEnumerator LoadAssetBundleCoroutine(string assetBundleName) {

    PlayAssetBundleRequest bundleRequest =
        PlayAssetDelivery.RetrieveAssetBundleAsync(assetBundleName);

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

            // 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(() => bundleRequest.Status != AssetDeliveryStatus.WaitingForWifi);
        }

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

        yield return null;
    }

    if (bundleRequest.Error != AssetDeliveryErrorCode.NoError) {
        // There was an error retrieving the bundle. 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. Retrieve AssetBundle from request.AssetBundle.
    AssetBundle assetBundle = bundleRequest.AssetBundle;

برای کسب اطلاعات بیشتر درباره مدیریت خطاها، فهرست AssetDeliveryErrorCodes را ببینید.

روش‌های دیگر Play Core API

در زیر چند روش اضافی «میانای برنامه‌سازی کاربردی» که ممکن است بخواهید در برنامه‌تان استفاده کنید آورده شده است.

بررسی اندازه بارگیری

با فراخوانی ناهمزمان Google Play و تنظیم روش بازخوانی برای زمانی که عملیات تکمیل می‌شود، اندازه AssetBundle را بررسی کنید:

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 آزمایش کنید.