unity AssetBundle 详解

什么是 AssetBundle

AssetBundle(简称AB包)是一个资源压缩包,可以包含模型、贴图、音频、预制体等。如在网络游戏中需要在运行时加载资源,而AssetBundle可以将资源构建成 AssetBundle 文件。

压缩模式

AssetBundle 提供了三种压缩格式

  • LZMA压缩(BuildAssetBundleOptions.None):unity中默认的压缩方式,优点是会将文件压缩的非常小,缺点是每次使用都需要将压缩的文件全部解压,非常耗费时间,可能会造成游戏的卡顿,不推荐在项目中使用。
  • 不压缩(BuildAssetBundleOptions.UncompressedAssetBundle):优点是需要加载资源时速度非常快,缺点是构建的 AssetBundle 资源文件会比较大。
  • LZ4压缩(BuildAssetBundleOptions.ChunkBasedCompression):是LZMA和不压缩之间的折中方案,构建的 AssetBundle 资源文件会略大于 LZMA 压缩,但是在加载资源时不需要将所有的资源都加载下来,所以速度会比 LZMA 快。建议项目中使用它。

AssetBundle使用

如图中所示选择需要构建 AssetBundle 的资源,在下方输入资源名称和后缀。
在这里插入图片描述

代码构建 AssetBundle

[MenuItem("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
    
    
        string dir = "Assets/StreamingAssets";
        if (Directory.Exists(dir) == false)
        {
    
    
            Directory.CreateDirectory(dir);
        }
        //BuildTarget.StandaloneWindows64 选择构建平台
        //BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64); //LZMA
        BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.ChunkBasedCompression, BuildTarget.StandaloneWindows64); //LZ4
        //BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.UncompressedAssetBundle, BuildTarget.StandaloneWindows64); //不压缩        

AssetBundle 加载

我们可以使用四种不同的方法来加载 AssetBundle。

  • AssetBundle.LoadFromMemoryAsync
  • AssetBundle.LoadFromFile
  • WWW.LoadfromCacheOrDownload
  • UnityWebRequestAssetBundle 和 DownloadHandlerAssetBundle

AssetBundle.LoadFromMemoryAsync

从内存区域异步创建 AssetBundle。

 /// <summary>
    /// 从本地异步加载AssetBundle资源
    /// </summary>
    /// <param name="path">路径</param>
    /// <returns></returns>
    IEnumerator LoadFromMemoryAsync(string path)
    {
    
    
        AssetBundleCreateRequest createRequest = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));
        yield return createRequest;
        AssetBundle bundle = createRequest.assetBundle;
        var prefab = bundle.LoadAsset<GameObject>("bullet");
        Instantiate(prefab);
    }

AssetBundle.LoadFromMemory由AssetBundle.LoadFromMemoryAsync变化而来,与 LoadFromMemoryAsync 相比,该版本是同步的,将等待 AssetBundle 对象创建完毕才返回。

		AssetBundle bundle = AssetBundle.LoadFromMemory(File.ReadAllBytes(ABPath));
        var prefab = bundle.LoadAsset<GameObject>("bullet");
        Instantiate(prefab);

AssetBundle.LoadFromFile

从磁盘上的文件同步加载 AssetBundle。
该函数支持任意压缩类型的捆绑包。 如果是 lzma 压缩,则将数据解压缩到内存。可以从磁盘直接读取未压缩和使用块压缩的捆绑包。

与 LoadFromFileAsync 相比,该版本是同步的,将等待 AssetBundle 对象创建完毕才返回。

这是加载 AssetBundle 的最快方法。

		AssetBundle ab = AssetBundle.LoadFromFile(ABPath);
        var go = ab.LoadAsset<GameObject>("bullet");
        Instantiate(go);

LoadFromFileAsync AssetBundle 的异步创建请求。加载后使用 assetBundle 属性获取 AssetBundle。
从磁盘上的文件异步加载 AssetBundle。

该函数支持任意压缩类型的捆绑包。 如果是 lzma 压缩,则将数据解压缩到内存。可以从磁盘直接读取未压缩和使用块压缩的捆绑包。

这是加载 AssetBundle 的最快方法。

IEnumerator LoadFromFileASync(string path)
    {
    
    
        AssetBundleCreateRequest createRequest = AssetBundle.LoadFromFileAsync(path);
        yield return createRequest;
        AssetBundle bundle = createRequest.assetBundle;
        if (bundle == null)
        {
    
    
            Debug.Log("Failed to load AssetBundle!");
            yield break;
        }
        var parefab = bundle.LoadAsset<GameObject>("bullet");
        Instantiate(parefab);
    }

WWW.LoadfromCacheOrDownload(已弃用)

本API已弃用,建议使用 UnityWebRequest。
从缓存中加载具有指定版本号的 AssetBundle。如果当前未缓存该 AssetBundle,则自动下载该 AssetBundle 并将其存储在缓存中,以便将来从本地存储检索。

 IEnumerator LoadFromCacheOrDownload()
    {
    
    
        //Caching.ready 如果缓存系统已准备就绪,返回 true。
        while (!Caching.ready)
            yield return null;
        //C:\Users\mfbf\AppData\LocalLow\Unity WWW缓存地址
        using (var www = WWW.LoadFromCacheOrDownload("http://127.0.0.1:8080/PC/attack/bullet.lian", 2))
        {
    
    
            yield return www;
            if (!string.IsNullOrEmpty(www.error))
            {
    
    
                Debug.Log(www.error);
                yield return null;
            }
            var bundle = www.assetBundle;

            var parefab = bundle.LoadAsset<GameObject>("bullet");
            Instantiate(parefab);
        }
    }

UnityWebRequestAssetBundle 和 DownloadHandlerAssetBundle

UnityWebRequestAssetBundle 此方法将 DownloadHandlerAssetBundle 附加到 UnityWebRequest。

DownloadHandlerAssetBundle.GetContent(UnityWebRequest) 作为参数。GetContent 方法将返回你的 AssetBundle 对象。

  IEnumerator WEB(string url)
    {
    
            
        UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(url,3,0);
        //此方法将返回 WebRequestAsyncOperation 对象。在协程内部生成 WebRequestAsyncOperation 将导致协程暂停,
        //直到 UnityWebRequest 遇到系统错误或结束通信为止。
        yield return  request.SendWebRequest();
        //如果加载失败
        if (request.result != UnityWebRequest.Result.Success)
        {
    
    
            Debug.Log(request.error);
            yield break;
        }
        //返回下载的 AssetBundle 或 null。
        
        AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(request);
        var parefab = bundle.LoadAsset<GameObject>("bullet");
        Instantiate(parefab);
    }

猜你喜欢

转载自blog.csdn.net/lian_hang/article/details/124976070