שילוב העברת נכסים (Unity)

בשילוב של העברת נכסים, משחקי Unity יכול לגשת לחבילות נכסים באמצעות 'ערכי כתובת' או AssetBundles. כתובות ה-URL הן פתרון עדכני יותר ומומלץ להצגת נכסים עבור משחקים שפותחו באמצעות Unity 2019.4 ואילך, ואילו AssetBundles מספקת תמיכה בחבילות נכסים ב-Unity 2017.4 ו-2018.4.

כתובות URL ל-Unity

במשחקים שנוצרו בגרסה Unity 2019.4 ואילך יש להשתמש כתובות שניתנות לכתובות להעברת נכסים ב-Android. Unity מספקת API של Play Asset Delivery (PAD) לטיפול בחבילות נכסים של Android באמצעות 'כתובות עם כתובות'. מידע על השימוש ניתן להוסיף לכתובות:

שימוש בקובצי AssetBundle

במשחקים שפותחו בגרסאות Unity 2017.4 ו-2018.4 אפשר להשתמש בקובצי AssetBundle לנכסים ב-Android. אחדות AssetBundle מכילים נכסים טוריים שמנוע Unity יכול לטעון בהם בזמן האפליקציה פועלת. הקבצים האלה ספציפיים לפלטפורמה (לדוגמה, הקבצים מיועדים Android), וניתן להשתמש בו בשילוב עם חבילות נכסים. ברוב המקרים, קובץ AssetBundle אחד ארוז בחבילת נכסים אחת, יחד עם החבילה באמצעות שם זהה לזה של AssetBundle. אם רוצים יותר גמישות ביצירת חבילת נכסים, להגדיר את חבילת הנכסים באמצעות ה-API.

בזמן הריצה, צריך להשתמש ב-Play Asset Delivery ל-Unity class כדי לאחזר AssetBundle ארוז בחבילת נכסים.

דרישות מוקדמות

  1. ניתן להוריד את הגרסה האחרונה של הפלאגין Play Asset Delivery Unity מחבילות של Google עבור Unity.

  2. יצירת AssetBundles ב-Unity

הגדרת AssetBundles באמצעות ממשק המשתמש

  1. מגדירים כל AssetBundle בחבילת נכסים:

    1. בוחרים באפשרות Google > קובץ Android App Bundle > הגדרות להעברת נכסים.
    2. כדי לבחור תיקיות שמכילות ישירות קובצי AssetBundle, לוחצים על Add תיקייה.

  2. בכל חבילה, משנים את מצב ההעברה לזמן התקנה, מהיר לעקוב, או על פי דרישה. פתרו שגיאות או יחסי תלות וסגרו את חלון.

  3. בוחרים באפשרות Google > יוצרים קובץ Android App Bundle כדי ליצור את ה-App Bundle.

  4. (אופציונלי) מגדירים את ה-App Bundle כך שיתמוך במרקם שונה דחיסה.

הגדרת חבילות נכסים באמצעות ה-API

אפשר להגדיר את העברת הנכסים באמצעות סקריפטים של כלי העריכה שניתן להריץ כחלק של מערכת build אוטומטית.

משתמשים ב AssetPackConfig class כדי להגדיר אילו נכסים לכלול בגרסת build של קובץ 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);
}

אפשר גם להשתמש BuildBundle method במחלקה Bundletool כדי ליצור קובץ Android App Bundle עם נכס חבילות, שניתנו BuildPlayerOptions וגם AssetPackConfig.

למדריך מודרך, אפשר לעיין שימוש ב-Play Asset Delivery ב-Codelab של משחקי Unity.

שילוב עם Play Asset Delivery Unity API

ממשק API ל-Unity API ל-Play Asset Delivery מספקת את הפונקציונליות לשליחת בקשות של חבילות נכסים, ניהול הורדות, בתהליך גישה לנכסים. קודם צריך להוסיף את הפלאגין של Unity לפרויקט.

הפונקציות שבהן משתמשים ב-API תלויות באופן שבו יצרתם את חבילות הנכסים.

אם חבילות נכסים שנוצרו באמצעות ממשק המשתמש של יישומי הפלאגין, בוחרים בחבילות נכסים שהוגדרו לפלאגין.

אם חבילות נכסים שנוצרו באמצעות ה-API (או ממשק המשתמש של יישומי הפלאגין), בוחרים חבילות נכסים בהגדרת API.

הטמעת ה-API בהתאם לסוג ההעברה חבילת הנכסים שאליה רוצים לגשת. השלבים האלה מוצגים תרשים זרימה.

תרשים הזרימה של חבילת הנכסים עבור הפלאגין

איור 1. תרשים זרימה לגישה לחבילות נכסים

אחזור AssetBundles

ייבא את הספרייה ב-Play Asset Delivery ולקרוא 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;
}

הורדות גדולות

ניתן להוריד חבילות נכסים שגדולות מ-200MB באופן אוטומטי, אבל רק ברשת 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;
    }
}

ביטול בקשה (על פי דרישה בלבד)

אם אתם צריכים לבטל את הבקשה לפני ש- AssetBundles נטענים לזיכרון, לקרוא AttemptCancel() ב-method PlayAssetBundleRequest object:

// 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

בהמשך מפורטות כמה שיטות API נוספות שכדאי להשתמש בהן באפליקציה.

בדיקת גודל ההורדה

בדיקת הגודל של AssetBundle באמצעות ביצוע קריאה אסינכרונית ל-Google Play והגדרת שיטת קריאה חוזרת (callback) לסיום הפעולה:

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

אפשר להסיר 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.