AssetBundle資源打包web
1.AssetLabels資源標籤算法
文件名:資源打包成AssetBundle後的文件名,相似於壓縮包的名字
後綴:自定義
文件名和後綴名都是小寫格式(大寫會自動轉爲小寫)
2. BuildPipeline.BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform) 打包全部設置了AssetLabel的資源
outputPath:路徑,打包出來的AssetBunlde文件存放的位置
BuildAssetBundleOptions:選項,設置AssetBundle打包過程當中壓縮方式緩存
BuildAssetBundleOptions枚舉選項:服務器
None使用LZMA壓縮算法進行壓縮,打包後資源體積最小
UncompressedAssetBundle不壓縮,打包後的AssetBundle體積最大,可是加載速度最快
ChunkBasedCompression使用LZ4壓縮算法進行壓縮,打包後的AssetBundle體積和加載速度介於上面兩者之間
BuildTarget:平臺,AssetBundle是平臺之間不兼容的,IOS,Android是兩套資源ui
在AssetLabels區域填寫AssetBundle名稱的時候,名稱是能夠分目錄嵌套的:文件夾名/文件名url
AssetBundle打包後的資源包,分兩部分組成:spa
1.資源打包出來的AssetBundle文件
2.AssetBundle文件配套的manifest文本文件3d
manifest文件code
manifest文件用於專門存儲打包後的AssetBundle文件的基本信息,主要包含:
CRC校驗碼:相似於MD5,用於計算出該資源的一個特殊信息標示
ClassTypes列表:當前資源關聯使用到了Unity中的哪些類,這些類是以編號索引的形式存在的,每一個編號都對應一個類文件
Assets:AssetsBundle裏包含了哪些資源文件
Dependencies:依賴orm
在打包出來的AssetBundle文件中,有一個特殊的manifest文件,和AssetBundle存放的文件夾同名,且只在根文件夾下有惟一的一個
這個manifest文件能夠稱做"AssetBundle目錄文件",它存儲了打包出來的全部AssetBundle的文件的索引信息
經過這個目錄文件,能夠找到全部的AssetBundle文件
AssetBundle資源加載
將項目資源打包成AssetBundle後,通常有兩種操做
一.將這些AssetBundle留着項目工程中,當成普通資源使用
1.加載AssetBundle資源到內存
AssetBundle ab = AssetBundle.LoadFromFile("路徑");加載AssetBundle資源到內存,返回一個AssetBundle對象
2.從AssetBundle中獲取資源
T res = ab.LoadAsset<T>("資源名");
3.實例化
打包
[MenuItem("xx/xxx")] public static void Build_WINDOWS64() { string outputPath = Path.Combine(Application.streamingAssetsPath, "Data"); if (!Directory.Exists(outputPath)) Directory.CreateDirectory(outputPath); BuildPipeline.BuildAssetBundles(outputPath, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);//本身選擇平臺 AssetDatabase.Refresh(); }
加載
using System.Collections; using System.Collections.Generic; public class AssetBundleManager { private readonly string _path = UnityEngine.Application.streamingAssetsPath + "/Data/"; private static AssetBundleManager _instance; private bool mIsLoadingEnd = false; public bool IsLoadingEnd { get { return mIsLoadingEnd; } } private List<string> mLoadingNames; private Dictionary<string, UnityEngine.Object> mAssets; private Dictionary<string, UnityEngine.Texture2D> mTexture2Ds; public static AssetBundleManager GetInstance() { if (_instance == null) { _instance = new AssetBundleManager(); } return _instance; } private AssetBundleManager() { mLoadingNames = new List<string>(){ //todo:要加載的資源名 }; mAssets = new Dictionary<string, UnityEngine.Object>(); mTexture2Ds = new Dictionary<string, UnityEngine.Texture2D>(); } /// <summary> /// 加載assetsbundle
/// 記得先加載到內存StartCoroutine(AssetBundleManager.GetInstance().Loading()); /// </summary> public IEnumerator Loading() { foreach (var nameAndType in mLoadingNames) { string filename = _path + nameAndType.ToLower(); UnityEngine.AssetBundleCreateRequest request = UnityEngine.AssetBundle.LoadFromFileAsync(filename); yield return request; LoadAsset(request.assetBundle); } mIsLoadingEnd = true; } private UnityEngine.AssetBundle LoadAssetBundle(string fileName) { UnityEngine.AssetBundle AB = UnityEngine.AssetBundle.LoadFromFile(_path + fileName); return AB; } private void LoadAsset(UnityEngine.AssetBundle ab) { UnityEngine.Object[] assets = ab.LoadAllAssets(); for (int i = 0; i < assets.Length; i++) { //一張圖片的AssetsBundle包含自身Texture2D和它裏面所有Sprite,有可能重名 if (!typeof(UnityEngine.Texture2D).Equals(assets[i].GetType())) mAssets.Add(assets[i].name, assets[i]); else mTexture2Ds.Add(assets[i].name, assets[i] as UnityEngine.Texture2D); } } /// <summary> /// 從assetbundle獲取texture2d /// </summary> public UnityEngine.Texture2D GetTexture2D(string name) { UnityEngine.Texture2D obj; mTexture2Ds.TryGetValue(name, out obj); return obj; } /// <summary> /// 從assetbundle獲取Object /// </summary> public UnityEngine.Object GetAsset(string name) { UnityEngine.Object obj; mAssets.TryGetValue(name, out obj); return obj; } }
二.將這些AssetBundle上傳服務器,客戶端第一次運行時從服務器下載AssetBundle緩存到本地再使用(實現客戶端的安裝包與資源分離,下降客戶端安裝包的體積)
1.服務器端下載主文件
從服務器端下載AssetBundle須要web路徑地址,每個地址對應一個AssetBundle文件.咱們不可能在代碼中寫幾十上百個文件的web地址,因此咱們須要先下載"目錄AssetBundle文件",而後經過它來間接獲取其餘AssetBundle文件的下載路徑地址.
須要引入命名空間using UnityEngine.Networking;
using System.Collections; using System.IO; using UnityEngine; using UnityEngine.Networking; public class TestAssetBundle : MonoBehaviour { private string mainAssetBundleURL = @"http://www.xxx.com.xxx/AssetBundleFile"; private string allAssetBundleURL = @"http://www.xxx.com.xxx/"; void Start() { StartCoroutine(DownloadMainAssetBundle()); } /// <summary> /// 下載目錄AssetBundle文件 /// </summary> IEnumerator DownloadMainAssetBundle() { //建立一個獲取AssetBundle文件的web請求 UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(mainAssetBundleURL); //發送web請求 yield return request.SendWebRequest(); //從請求中獲取內容,返回AssetBundle類型的數據 AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request); //從"目錄AssetBundle"中獲取manifest數據 AssetBundleManifest manifest = ab.LoadAsset<AssetBundleManifest>("AssetBundleManifest"); //獲取manifest文件中全部的AssetBundle的名稱信息 string[] names = manifest.GetAllAssetBundles(); foreach (var name in names) { StartCoroutine(DownloadAssetBundleAndSave(allAssetBundleURL + name)); } } /// <summary> /// 下載AssetBundle並保存到本地 /// </summary> IEnumerator DownloadAssetBundleAndSave(string url) { UnityWebRequest request = UnityWebRequest.Get(url); yield return request.SendWebRequest(); // 截取路徑地址中的文件名(須要引入System.IO) string fileName = Path.GetFileName(url); SaveAssetBundle(fileName, request.downloadHandler.data); } /// <summary> /// 存儲AssetBundle爲本地文件 /// </summary> private void SaveAssetBundle(string fileName, byte[] bytes) { //建立一個文件信息對象(System.IO) FileInfo fileInfo = new FileInfo(Application.streamingAssetsPath + "//" + fileName); //建立一個文件流對象 FileStream fs = fileInfo.Create(); //經過文件流對象,往文件內寫入信息 fs.Write(bytes, 0, bytes.Length); //文件寫入存儲到硬盤 fs.Flush(); //關閉文件流對象 fs.Close(); //銷燬文件對象 fs.Dispose(); } }