یکپارچه سازی تحویل دارایی (Unity)

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

Unity Addressables

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

از فایل های AssetBundle استفاده کنید

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

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

پیش نیازها

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

OpenUPM-CLI

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

openupm add com.google.play.assetdelivery

OpenUPM

  1. تنظیمات مدیریت بسته را با انتخاب گزینه منوی Unity Edit > Project Settings > Package Manager باز کنید.

  2. OpenUPM را به عنوان یک رجیستری با محدوده به پنجره Package Manager اضافه کنید:

    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. منوی کشویی مدیریت دامنه را برای انتخاب My Registries تنظیم کنید.

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

واردات از GitHub

  1. آخرین نسخه .unitypackage را از GitHub دانلود کنید.

  2. فایل .unitypackage را با انتخاب گزینه منوی Unity Assets > Import package > Custom Package و وارد کردن همه موارد وارد کنید.

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

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

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

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

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

  3. Google > Build Android App Bundle را برای ساختن بسته نرم افزاری انتخاب کنید.

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

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

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

از کلاس AssetPackConfig استفاده کنید تا مشخص کنید که کدام دارایی ها در یک ساخت Android App Bundle و همچنین حالت تحویل دارایی ها گنجانده شود. این بسته‌های دارایی نیازی به داشتن 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);
}

با توجه به BuildPlayerOptions و AssetPackConfig ، می‌توانید از روش استاتیک BuildBundle در کلاس Bundletool برای ایجاد یک Android App Bundle با بسته‌های دارایی استفاده کنید.

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

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

Play Asset Delivery Unity API عملکردی را برای درخواست بسته‌های دارایی، مدیریت دانلودها و دسترسی به دارایی‌ها ارائه می‌کند. حتما ابتدا افزونه Unity را به پروژه خود اضافه کنید .

عملکردهایی که در API استفاده می کنید به نحوه ایجاد بسته های دارایی بستگی دارد.

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

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

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

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

شکل 1. نمودار جریان برای دسترسی به بسته های دارایی

یک بسته دارایی را بازیابی کنید

کتابخانه Play Asset Delivery را وارد کنید و روش 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.
}

بارگذاری دارایی ها در حافظه

پس از تکمیل درخواست، از یکی از این توابع برای بارگیری دارایی ها در حافظه استفاده کنید:

  • از PlayAssetPackRequest.GetAssetLocation() برای دریافت یک شی AssetLocation استفاده کنید. این مسیر، افست و اندازه دارایی را فراهم می کند تا بتوان آن را از دیسک بارگیری کرد.
  • اگر دارایی AssetBundle است، می‌توانید از روش راحت PlayAssetPackRequest.LoadAssetBundleAsync(assetPath) استفاده کنید. مسیر دارایی که عبور می کنید باید با مسیر AssetBundle از داخل بسته دارایی مطابقت داشته باشد. این یک AssetBundleCreateRequest را برمی گرداند.

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

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

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

در زیر چند روش 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();
    }
}

AssetBundles را حذف کنید

می‌توانید بسته‌های دارایی سریع و درخواستی را که در حال حاضر در حافظه بارگذاری نشده‌اند، حذف کنید. تماس ناهمزمان زیر را انجام دهید و یک روش بازگشت به تماس را برای زمانی که آن کامل شد تنظیم کنید:

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