Unity 加载AssetBundle

随着Unity的版本更新,加载AssetBundle的API也不断变化,要熟悉这些API才能把资源包管理的更好,在这里作个总结。html

WWW

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;
        }
    }
}

UnityWebRequest

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

加载本地资源包最快的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...

相关文章
相关标签/搜索