• 35648

    文章

  • 23

    评论

  • 20

    友链

  • 最近新加了很多技术文章,大家多来逛逛吧~~~~
  • 喜欢这个网站的朋友可以加一下QQ群,我们一起交流技术。

Unity 加载AssetBundle

欢迎来到阿八个人博客网站。本 阿八个人博客 网站提供最新的站长新闻,各种互联网资讯。 喜欢本站的朋友可以收藏本站,或者加QQ:我们大家一起来交流技术! URL链接:https://www.abboke.com/jsh/2019/0704/5392.html 1190000019656656

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

WWW

Unty4.x - 5.x 用WWW类加载
WWW.LoadFromCacheOrDownload() 通过Url和版本号自动缓存资源包 注意必须是资源包 不能是其他格式 不能加密

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加载速度更快 内存占用更小 缺点是包体积大

参考资料:
《关于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...

下载远程文件最好的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) 2271ms 52M 加载速度最快 内存最小 只缓存索引
AssetBundle.LoadFromFileAsync(path) --ms --M 加载速度极快 内存最小 异步版LoadFromFile
AssetBundle.LoadFromMemory(path) --ms --M 数据完全缓存在内存里 内存占用最大
AssetBundle.LoadFromMemoryAsync(path) --ms --M 数据完全缓存在内存里 异步版LoadFromMemory

总结:
多看官方样例,多看官方文档,熟悉官方API才能更好的掌控性能。
如果对资源包的处理比较复杂,需要自己定制资源包生成器和加载器。
注意资源包的压缩格式和加载API,对性能影响非常大。
LZMA:高压缩、低性能、高内存、性价比太低,不推荐使用。
LZ4 :中压缩、高性能、低内存、性价比最高,推荐使用。
两者性能差距非常大,但体积相差不大,推荐使用LZ4,不推荐LZMA
如果必须严格控制资源包体积,可以考虑用高压缩格式传输文件,内存解压为LZ4后保存到本地。
(LoadFromCacheOrDownload()提供的就是这个功能)

参考资料:
《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...

相关文章

暂住......别动,不想说点什么吗?
  • 全部评论(0
    还没有评论,快来抢沙发吧!