随着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...