簡單總結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。
  • 需要使用MenuItem特性。
  • 點擊菜單項觸發的函數是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的壓縮包鏡像文件釋放。

注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com