שימוש בחבילת נכסים ב-Unity

Unity יש תכונות שימושיות רבות, אחת מהן היא תמיכה בחבילות נכסים.

מהן חבילות נכסים?

חבילות נכסים הן קבצים המכילים נכסי משחק, החל מנכסים פשוטים כמו מודלים תלת מימדיים, טקסטורות וקטעי שמע, ועד למורכבים יותר, כמו Scenes ו-Prefabs.

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

מתי להשתמש בחבילות נכסים?

השתמש ב-Asset Bundles כאשר למשחק שלך יש הרבה נכסים והכללתם ב-build משפיעה על זמן ההורדה הראשוני.

ייצוא חבילות נכסים

ייצוא חבילות נכסים מתבצע בשני שלבים: הקצאת שמות חבילות נכסים ובנייתם ​​באמצעות העורך script.

הקצאת שמות של חבילות נכסים

כדי להקצות את השם של חבילת הנכסים, בחר את הנכס בתצוגת הפרויקט (זה יכול להיות Prefab, Texture, או אפילו סצנה), ואז בתצוגת המפקח בתחתית הקצה לחץ על התפריט הנפתח, ואז לחץ על 'New...' (או לחץ על שם חבילת הנכסים הקיים).

הקצאת אותו שם חבילה למספר נכסים תארוז אותם יחד באותו חבילת נכסים. מומלץ לארוז את הסצנות בנפרד משאר הנכסים.

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

בניית חבילות נכסים

כדי לבנות חבילות נכסים, בצע את השלבים הבאים:

  • צור תיקיה חדשה בשם Editor (אם אין לך)
  • צור סקריפט חדש בתוך תיקיית העורך, שם לו BuildAssetBundles ואז הדבק בתוכו את הקוד למטה:

BuildAssetBundles.cs

using UnityEngine;
using UnityEditor;

public class BuildAssetBundles
{
    [MenuItem("Build/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        string outputFolder = "Assets/__Bundles";

        //Check if __Bundles folder exist
        if (!AssetDatabase.IsValidFolder(outputFolder))
        {
            Debug.Log("Folder '__Bundles' does not exist, creating new folder");

            AssetDatabase.CreateFolder("Assets", "__Bundles");
        }

        BuildPipeline.BuildAssetBundles(outputFolder, BuildAssetBundleOptions.ChunkBasedCompression, EditorUserBuildSettings.activeBuildTarget);
    }
}

לאחר שמירתו תבחין שהוא יוסיף כפתור תפריט (Build -> Build AssetBundles). לחיצה עליו תבנה את חבילות הנכסים ותמקם אותם בתיקייה "__Bundles".

טוען חבילות נכסים

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

טעינת נכסים מחבילות הנכסים

הקוד שלהלן מוריד את חבילת הנכסים בשם "fpsplayer" ואז מחלץ את ה-Prefab בשם "FPSPlayer" ומציג אותו בסצנה:

        int assetBundleVersion = 1; // Changing this number will force Asset Bundle reload
        string assetBundlePath = "file://" + Application.dataPath + "/__Bundles/" + "fpsplayer"; // Path to Asset Bundle file
        using (UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle(assetBundlePath, (uint)assetBundleVersion, 0))
        {
            yield return www.SendWebRequest();

            if (www.isNetworkError || www.isHttpError)
            {
                Debug.LogError("AssetBundle Error: " + www.error);
                yield return null;
            }
            else
            {
                // Get downloaded Asset Bundle
                AssetBundle assetBundle = UnityEngine.Networking.DownloadHandlerAssetBundle.GetContent(www);
                // Extract Prefab named "FPSPlayer" from the Asset Bundle
                GameObject playerPrefab = assetBundle.LoadAsset("FPSPlayer") as GameObject;
                // Instantiate Player Prefab
                Instantiate(playerPrefab, Vector3.zero, Quaternion.identity);
                // Unload Asset Bundle from memory (but do not destroy the existing instance(s))
                assetBundle.Unload(false);
            }
        }

טוען סצנות מחבילות הנכסים

טעינת סצנת מחבילת הנכסים מתבצעת בצורה מעט שונה.

הקוד שלהלן יוריד את חבילת הנכסים עם סצנה ויהפוך אותו לזמין לטעינה:

        int assetBundleVersion = 1; // Changing this number will force Asset Bundle reload
        string assetBundlePath = "file://" + Application.dataPath + "/__Bundles/" + "testscene"; // Path to Asset Bundle file
        using (UnityEngine.Networking.UnityWebRequest www = UnityEngine.Networking.UnityWebRequestAssetBundle.GetAssetBundle(assetBundlePath, (uint)assetBundleVersion, 0))
        {
            yield return www.SendWebRequest();

            if (www.isNetworkError || www.isHttpError)
            {
                Debug.LogError("AssetBundle Error: " + www.error);
                yield return null;
            }
            else
            {
                // Get downloaded Asset Bundle (This will make the Scene available for load)
                AssetBundle assetBundle = UnityEngine.Networking.DownloadHandlerAssetBundle.GetContent(www);
                // Load the Scene extracted from the Asset Bundle
                UnityEngine.SceneManagement.SceneManager.LoadScene("TestScene");
            }
        }