隨着Unity的版本更新,加載AssetBundle的API也不斷變化,要熟悉這些API才能把資源包管理的更好,在這裏作個總結。html
Unty4.x - 5.x 用WWW類加載
WWW.LoadFromCacheOrDownload() 經過Url和版本號自動緩存資源包 注意必須是資源包 不能是其餘格式 不能加密segmentfault
www加載樣例:緩存
using UnityEngine; using System.Collections; public class LoadFromCacheOrDownloadExample : MonoBehaviour { IEnumerator Start() { while (!Caching.ready) yield return null; using (var www = WWW.LoadFromCacheOrDownload("http://myserver.com/myassetBundle.unity3d", 5)) { yield return www; if (!string.IsNullOrEmpty(www.error)) { Debug.Log(www.error); yield return null; } var myLoadedAssetBundle = www.assetBundle; var asset = myLoadedAssetBundle.mainAsset; } } }
Unity2018.1之後 官方建議用UnityWebRequest類代替WWW類
UnityWebRequest.GetAssetBundle() 兼容WWW.LoadFromCacheOrDownload()的功能 並提供了更多的功能異步
UnityWebRequest加載樣例:函數
using UnityEngine; using UnityEngine.Networking; using System.Collections; /// <summary> /// 下載測試 /// <para>原文地址:https://segmentfault.com/a/1190000019656656</para> /// </summary> public class WebRequestTest : MonoBehaviour { private void Start () { StartCoroutine(DoLoadFile()); } // 下載文本或二進制文件 private IEnumerator DoLoadFile() { string url = Application.streamingAssetsPath + "/" + "test.txt"; using (UnityWebRequest request = UnityWebRequest.Get(url)) { yield return request.SendWebRequest(); if (request.isHttpError || request.isNetworkError) { // 下載出錯 print(request.error); } else { // 下載完成 string text = request.downloadHandler.text; byte[] bytes = request.downloadHandler.data; } } } // 下載圖片 private IEnumerator DoLoadTexture() { string url = Application.streamingAssetsPath + "/" + "test.png"; using (UnityWebRequest request = UnityWebRequestTexture.GetTexture(url)) { yield return request.SendWebRequest(); if (request.isHttpError || request.isNetworkError) { // 下載出錯 print(request.error); } else { // 下載完成 Texture2D texture = (request.downloadHandler as DownloadHandlerTexture).texture; } } } // 下載AssetBundle private IEnumerator DoLoadAssetBundle() { string url = Application.streamingAssetsPath + "/" + "test.ab"; using (UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(url)) { yield return request.SendWebRequest(); if (request.isHttpError || request.isNetworkError) { // 下載出錯 print(request.error); } else { // 下載完成 AssetBundle assetBundle = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle; } } } }
加載本地資源包最快的API:
AssetBundle.LoadFromFile(path) 同步 注意必須是AssetBundle格式 能夠壓縮 不能加密
AssetBundle.LoadFromFileAsync(path) 異步 注意必須是AssetBundle格式 能夠壓縮 不能加密性能
官方文檔翻譯:測試
同步地從磁盤上的文件加載一個資源包。
該函數支持任何壓縮類型的包。在lzma壓縮格式下,數據將被解壓到內存中。未壓縮格式和塊壓縮格式能夠直接從磁盤讀取。
與LoadFromFileAsync相比,這個版本是同步的,在建立AssetBundle對象以前不會返回。
這是加載AssetBundle的最快方法。
《官方文檔》https://docs.unity3d.com/Scri...加密
PS:從官方文檔能夠看出 彷佛不壓縮或LZ40要比LZMA壓縮性能更好 百度後發現確實如此
LZ4要比LZMA加載速度更快 內存佔用更小 缺點是包體積大url
參考資料:
《關於LZMA和LZ4壓縮的疑惑解析》https://blog.csdn.net/weixin_...
《一樣的場景,分別用LZMA和LZ4壓縮方式,經過AssetBundle.LoadFromFile(Async)加載,內存上能夠相差多少》
https://answer.uwa4d.com/ques...
《AssetBundleCompression Bundle的壓縮格式》http://blog.sina.com.cn/s/blo....net
下載遠程文件最好的API:
UnityWebRequest.Get() 至關於之前的WWW下載 能夠是任意格式文件 能夠壓縮 能夠加密
能夠經過Get()下載文件後解壓縮保存到本地 用LoadFromFileAsync()讀取 加快加載速度
下載遠程資源包最好的API:
UnityWebRequest.GetAssetBundle() 注意必須是AssetBundle格式 能夠壓縮 不能加密
各API加載測試:
資源包大小:48.5M 壓縮格式:LZ4 測試平臺:PC 本地文件
API | 加載時間 | 內存上升 | 說明 |
---|---|---|---|
new WWW(path) | 49ms | 49M | 排除偏差 內存基本與資源體積一致 |
UnityWebRequest.Get(path) | 48ms | 49M | 排除偏差 內存基本與資源體積一致 |
AssetBundle.LoadFromFile(path) | 3ms | 1.1M | 加載速度最快 內存最小 只緩存索引 |
AssetBundle.LoadFromFileAsync(path) | 18ms | 1.1M | 加載速度極快 內存最小 異步版LoadFromFile |
AssetBundle.LoadFromMemory(path) | 78ms | 52M | 數據徹底緩存在內存裏 內存佔用最大 |
AssetBundle.LoadFromMemoryAsync(path) | 91ms | 51M | 數據徹底緩存在內存裏 異步版LoadFromMemory |
資源包大小:41.7M 壓縮格式:LZMA 測試平臺:PC 本地文件
API | 加載時間 | 內存上升 | 說明 |
---|---|---|---|
new WWW(path) | --ms | --M | 排除偏差 內存基本與資源體積一致 |
UnityWebRequest.Get(path) | --ms | --M | 排除偏差 內存基本與資源體積一致 |
AssetBundle.LoadFromFile(path) | --ms | 52M | 加載速度最快 內存最小 只緩存索引 |
AssetBundle.LoadFromFileAsync(path) | --ms | --M | 加載速度極快 內存最小 異步版LoadFromFile |
AssetBundle.LoadFromMemory(path) | --ms | --M | 數據徹底緩存在內存裏 內存佔用最大 |
AssetBundle.LoadFromMemoryAsync(path) | --ms | --M | 數據徹底緩存在內存裏 異步版LoadFromMemory |
總結:
隨着Unity版本的迭代,API不斷變化以適應更多的需求,管理資源包的API變得愈來愈複雜了,官方儘可能提供一個簡單易用的API幫助開發者自動處理這個過程,可是當開發者處理的狀況愈來愈複雜時,就須要本身定製資源包生成管理器和資源包加載管理器了,熟悉官方API才能更好的掌控性能,多看官方樣例。
參考資料:
《Unity Assetbundle的加載方式的效率和內存佔用》https://blog.csdn.net/u012740...
《WWW.LoadFromCacheOrDownLoad官方文檔》https://docs.unity3d.com/2018...
《UnityWebRequest.GetAssetBundle官方文檔》https://docs.unity3d.com/2018...
轉載請標明原文地址:https://segmentfault.com/a/11...