1. 程式人生 > >簡單總結AssetBundle的打包/解包

簡單總結AssetBundle的打包/解包

最近參考了各位大神的資源,初步學習了Unity的資源管理模式,包括在編輯器管理(使用AssetDatabase)和在執行時管理(使用Resources和AssetBundle)。在此簡單總結執行時用AssetBundle動態打包/解包資源的方法,方便自己回顧。

關於AssetBundle有很多的細節問題,在此先作個筆記,等更多的問題搞清楚了/有了新的理解,再接著補充/修改。

建立編輯器選單項,用於打包AssetBundle

using UnityEngine;
using System.Collections;
using System.Collections.Generic; // 需要使用List集合
using UnityEditor; // 建立編輯器選單項需要匯入這個檔案 public class CreateMenuItem { // 不需要繼承Mono [MenuItem("My MenuItem/Build AssetBundle")] public static void BuildBundle() { List<AssetBundleBuild> list = new List<AssetBundleBuild>(); // 多個資源可以打入一個包中,不確定個數時,可用List集合一個一個新增 AssetBundleBuild b = new
AssetBundleBuild(); b.assetBundleName = "1.unity3d"; // 用於載入該資源,相當於這個資源在AssetBundleBuild中的ID,因為AssetBundleBuild中可能有多個資源 b.assetNames = new string[] { "Assets/Resources/Images/1.jpg" }; // 這個AssetBundleBuild裡包含的哪些資源 list.Add(b); // 該方法不會自動生成資料夾,所以若指定的資料夾不存在,則打包失敗 BuildPipeline.BuildAssetBundles("Assets/Bundles"
, list.ToArray(), BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64); } }

打包成功後,在目標資料夾下多瞭如下4個檔案:
這裡寫圖片描述

關於製作編輯器選單項

  • 需要把該指令碼放在Editor目錄下,建議在Assets根目錄下新建“Editor”資料夾。
  • 需要匯入UnityEditor檔案。
  • 選單項的類不用繼承MonoBehaviour。
  • 點選選單項觸發的函式是static靜態的。

關於打包AssetBundle

  • assetBundleName : 該資源打入包後的名字,解包時可用該名字訪問到該資源。
  • assetNames : 要被打包的資源當前的相對路徑。
  • 打包函式:BuildPipeline.BuildAssetBundles()。
  • 打包函式要求傳入AssetBundleBuild[]陣列,因為一個AssetBundle壓縮包中可以被加入多個資源,可以使用動態陣列List來替代(不用指定陣列長度),使用集合的Add()方法將資源一個一個加入包中。
  • 關於引數BuildAssetBundleOptions,以前常用的選項BuildAssetBundleOptions.CollectDependencies和BuildAssetBundleOptions.CompleteAssets都已過時,官方文件解釋是這兩種選項現在都預設會被執行。關於這個引數我沒有過多的探究,這裡暫時選用了BuildAssetBundleOptions.None。
  • 方法的最後一個引數BuildTarget指定打包到哪個平臺下,這裡我用PC測試選擇BuildTarget.StandaloneWindows64。
  • 打包方法中填的目標資料夾路徑如果不存在,該方法不會建立該資料夾,打包失敗。
  • 這裡只是簡單的打包一個資源,沒有涉及打包多個資源時,不同資源有共通引用別的資源的問題,學習中。

載入/解包AssetBundle

public class LoadAssetBundle : MonoBehaviour {

    void Start () {
        StartCoroutine(Load());
    }

    // 載入AssetBundle壓縮包是個非同步過程,需要開啟協程
    IEnumerator Load()
    {
        // 步驟一:獲取AssetBundle壓縮包
        //  WWW www = new WWW("http://myserver/myBundle.unity3d"); // 從遠端伺服器下載
        //  WWW www = new WWW("File://" + Application.streamingAssetsPath + "1.unity3d"); // 手機上從本機載入
        WWW www = new WWW("File:///D:/Unity Projects/Learn Asset Manage/Assets/Bundles/1.unity3d"); // 從PC本機載入,是三個槓
        yield return www;

        AssetBundle build = www.assetBundle;
        Debug.Log(build); // 測試是否非空

        // 步驟二:解包獲取資源
        /*
        // 非同步載入,分幀操作
        AssetBundleRequest request = build.LoadAssetAsync("Assets/Prefabs/airplane.prefab", typeof(GameObject)); // 名字和型別是打包時確定的
        yield return request;
        GameObject go = request.asset as GameObject;
        */
        // 同步載入,速度更快,但可能會阻塞主執行緒
        GameObject go = build.LoadAsset<GameObject>("Assets/Prefabs/airplane.prefab");


        Instantiate(go, new Vector3(0, 0, 0), Quaternion.identity);

        // 完成後釋放原始映象檔案
        www.Dispose();
    }
}

注意點:

  • 載入AssetBundle壓縮包是個非同步過程,需要開啟協程。
  • 壓縮包的獲取方式有三種:從遠端伺服器、手機上本地載入、PC上本地載入。想要在手機上載入本地AssetBundle,需要將所需資源包存放在自建立的名為“StreamingAssets”的資料夾中,該資源才能釋出到真機上。參考Streaming Assets
  • 解AssetBundle包可以使用非同步或同步載入方式,前者分幀操作載入稍慢,後者載入更快但可能阻塞主執行緒。
  • 解壓完成後可以通過www.Dispose()方法將原WWW的壓縮包映象檔案釋放。