כשמשלבים העברת נכסים, משחקי Unity יכולים לגשת לחבילות נכסים באמצעות Addressables או AssetBundles. Addressables הוא הפתרון העדכני והמומלץ להעברת נכסים למשחקים שנוצרו ב-Unity מגרסה 2019.4 ואילך, בעוד ש-AssetBundles תומך בחבילות נכסים ב-Unity מגרסה 2017.4 ו-2018.4.
Unity Addressables
במשחקים שנוצרו ב-Unity מגרסה 2019.4 ואילך, צריך להשתמש ב-Addressables כדי לשלוח נכסים ל-Android. Unity מספקת ממשק API של Play Asset Delivery (PAD) לטיפול בחבילות נכסים ל-Android באמצעות Addressables. למידע נוסף על השימוש ב-Addressables:
שימוש בקובצי AssetBundle
במשחקים שנוצרו באמצעות Unity 2017.4 ו-2018.4 אפשר להשתמש בקובצי AssetBundle כדי להעביר נכסים ב-Android. קבצים מסוג AssetBundle ב-Unity מכילים נכסים בסריאליזציה שאפשר לטעון במנוע Unity בזמן שהאפליקציה פועלת. הקבצים האלה ספציפיים לפלטפורמה (לדוגמה, הם מפותחים ל-Android) וניתן להשתמש בהם בשילוב עם חבילות נכסים. בדרך כלל, קובץ AssetBundle אחד נארז בחבילת נכסים אחת, והשם של החבילה זהה לשם של AssetBundle. אם אתם רוצים גמישות רבה יותר ביצירת חבילת נכסים, תוכלו להגדיר אותה באמצעות ה-API.
בזמן הריצה, משתמשים בכיתה Play Asset Delivery for Unity כדי לאחזר AssetBundle שארוז בחבילת נכסים.
דרישות מוקדמות
- מגדירים את סביבת הפיתוח:
OpenUPM-CLI
אם OpenUPM CLI מותקן, אפשר להתקין את המרשם של OpenUPM באמצעות הפקודה הבאה:
openupm add com.google.play.assetdelivery
OpenUPM
פותחים את הגדרות מנהל החבילות על ידי בחירה באפשרות בתפריט של Unity Edit > Project Settings > Package Manager.
מוסיפים את 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
פותחים את תפריט מנהל החבילות על ידי בחירה באפשרות בתפריט של Unity Window (חלון) > Package Manager (מנהל החבילות).
בתפריט הנפתח של היקף הניהול, בוחרים באפשרות My Registries.
בוחרים את החבילה Google Play Integrity plugin for Unity מרשימת החבילות ולוחצים על Install.
ייבוא מ-GitHub
מורידים את הגרסה האחרונה של
.unitypackage
מ-GitHub.מייבאים את הקובץ
.unitypackage
על ידי בחירה באפשרות בתפריט של Unity Assets > Import package > Custom Package (נכסים > ייבוא חבילה > חבילה מותאמת אישית) וייבוא כל הפריטים.
הגדרת AssetBundles באמצעות ממשק המשתמש
מגדירים כל AssetBundle בחבילת נכסים:
- בוחרים באפשרות Google > Android App Bundle > Asset Delivery Settings.
- כדי לבחור תיקיות שמכילות ישירות קובצי AssetBundle, לוחצים על Add Folder.
בכל חבילת מודעות, משנים את Delivery Mode ל-Install Time, ל-Fast Follow או ל-On Demand. מתקנים את השגיאות או יחסי התלות וסוגרים את החלון.
בוחרים באפשרות Google > Build Android App Bundle כדי ליצור את חבילת האפליקציות.
(אופציונלי) מגדירים את חבילת האפליקציות כך שתתמוך בפורמטים שונים של דחיסת טקסטורות.
הגדרת חבילות נכסים באמצעות ה-API
אפשר להגדיר את העברת הנכסים באמצעות סקריפטים של עורכי טקסט, שאפשר להריץ כחלק ממערכת build אוטומטית.
משתמשים בכיתה AssetPackConfig
כדי להגדיר אילו נכסים לכלול ב-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); }
אפשר גם להשתמש ב-method הסטטי BuildBundle
בכיתה Bundletool
כדי ליצור Android App Bundle עם חבילות נכסים, על סמך BuildPlayerOptions ו-AssetPackConfig
.
הדרכה מודרכת מפורטת זמינה במאמר שימוש ב-Play Asset Delivery במשחקי Unity Codelab.
שילוב עם Play Asset Delivery Unity API
Play Asset Delivery Unity API מספק את הפונקציונליות לבקשה של חבילות נכסים, לניהול ההורדות ולגישה לנכסים. חשוב להוסיף את הפלאגין של Unity לפרויקט לפני כן.
הפונקציות שבהן משתמשים ב-API תלויות באופן שבו יצרתם את חבילות הנכסים.
אם יצרתם חבילות נכסים באמצעות ממשק המשתמש של הפלאגין, בוחרים באפשרות חבילות נכסים שהוגדרו באמצעות הפלאגין.
אם יצרתם חבילות נכסים באמצעות ה-API (או ממשק המשתמש של הפלאגין), בוחרים באפשרות חבילות נכסים שהוגדרו באמצעות API.
מטמיעים את ה-API בהתאם לסוג המסירה של חבילת הנכסים שאליה רוצים לגשת. השלבים האלה מוצגים בתרשים התהליך הבא.
אחזור AssetBundles
מייבאים את ספריית Play Asset Delivery ומפעילים את ה-method 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 והפצה על פי דרישה
הקטעים האלה חלים על חבילות נכסים מסוג 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 נטענים בזיכרון, צריך לבצע קריאה ל-method 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. }
שליחת בקשה לאסימונים של חבילות נכסים באופן אסינכרוני
ברוב המקרים, כדאי להשתמש ב-Coroutines כדי לבקש חבילות נכסים באופן אסינכרוני ולעקוב אחרי ההתקדמות, כפי שמתואר בהמשך:
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
אפשר להסיר חבילות נכסים דיגיטליים מסוג 'מעקב מהיר' ו'על פי דרישה' שלא נטענו כרגע לזיכרון. מריצים את הקריאה האסינכרונית הבאה ומגדירים שיטה להודעה חוזרת (callback) כשהיא מסתיימת:
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.