AssetBundle

打包AssetBundle文件

一、什么是AssetBundle

基本可以给为两点:
1. 它是一个存在于硬盘上的文件。可以称之为压缩包。这个压缩包可以认为是一个文件夹,里面包含了多个文件。这些文件可以认为两类:Serialized File和Resources File。

Serialized File (序列化文件):资源被打碎放在一个对象中,最后统一被写进一个单独的文件(只有一个、在游戏加载时才能看到)。 例如:Prefab
Resources File(源文件):某些二进制资源(图片,声音)被单独保存,方便快速加载。 (在本地可以直接看到)如图所示:

  1. 它是一个AssetBundle对象,我们可以同代码从一个特定的压缩包加载出来的对象。这个对象包含了所有我们当初添加到这个压缩包里面的内容,我们可以通过这个对象加载出来使用。

二、用处:

  1. AssetBundle相当于一个压缩包包含模型、贴图、预制体声音,甚至整个场景,可以在游戏运行的时候被加载;
  2. AssetBundle自身保存着互相的依赖关系;
  3. 压缩包可以使用LZMA和LZ4压缩算法,减少包大小,更快的进行网络传输;
  4. 把一些可以下载内容放在AssetBundle里面, 可以减少安装包的大小;

三、AssetBundle使用流程。

  1. 指定资源的AssetBundle属性设置。
    如图:

    None: 默认的,表示不打包。
    New: 创建打包,(例如:wall、scene/wall、scene/cylinderwall)红色圈圈出是设置文件的后缀。默认为none 如图所示:

    打包出来的效果:


    Remove Unused Names: (删除没有用的)

  2. 构建AssetBundle包(重要代码可在Unity官方手册中AssetBundle/AssetBundle Workflow中的Build the AssetBundle)。我下面也写到的。

using UnityEditor;
using UnityEngine;
using System.IO;

public class CreateAssetBundles : MonoBehaviour
{

    [MenuItem("Assets/BuildAssetBundles")]          //在Asset菜单栏里添加一个菜单项,命名为BuildAssetBundles
    static void BuildAllAssetBundles()
    {
        //设置路径(在项目的根目录)创建的一个文件夹AssetBundles
        string dir = "AssetBundles";
        //如果没有则创建一个
        if (Directory.Exists(dir)==false)
        {
            Directory.CreateDirectory(dir);
        }

        //参数解释:路径,Build的一个选项,目标平台(例如:Windows,安卓)
        BuildPipeline.BuildAssetBundles(dir, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);
    }
}

3.上传包
4. 加载AssetBundle包和包里的资源

AssetBundle《二》

一、AssetBundle_分组策略
  1. 把经常更新的资源放在一个单独的包里面,跟不经常更新的包分离
  2. 把需要同时加载的资源放在一个包里面
  3. 可以吧其他包共享的资源放在一个单独得包里面
  4. 把一些需要同时加载的小资源打成包
  5. 如果对于一个同一个资源有两个版本,可以考虑通过后缀来区分
二、依赖打包

(避免被共享的素材被重复打包)

使用共同的材质打包测试:

  1. 普通打包,只将物体分别打包。如图:
  2. 依赖打包,将材质物体分别打包。如图:

显而易见,使用后者将减少空间,并且节省下载速度。(并且unity会自动去寻找依赖关系,不需要再用代码控制。)

构建AssetBundle包(二)

(即Build,接之前所讲)
1. Build:路径(硬盘上随意地址)
2. BuildAssetBundleOptions:(Build的一个选项)
1)全部选项如下地址:
Unity官方手册
2)主要介绍如一下三个:
None:默认(使用LZMA算法压缩,压缩的包更小,但是加载时间更长。使用之前需要整体解压。一旦被解压,这个包会使用LZ4重新压缩。使用资源的时候不需要整体解压。在下载的时候可以使用LZMA算法,一旦他被下载了之后,它会使用LZ4算法保存到本地上。)
UncompressedAssetBundle:不压缩,包大,加载快
ChunkBasedCompression:使用LZ4压缩,压缩率没有LZMA高,但是我肯可以加载指定资源而不用解压全部。

注意:使用LZ4压缩,可以获得跟不压缩相媲美的加载速度,而且比不压缩包小。

  1. BuildTarget:选择build出来的AB包要使用的平台(Android,Windows..)
测试三种压缩方法的包的大小
  1. None:
  2. ChunkBasedCompression(LZ4)
  3. UncompressedAssetBundle

所以一般情况下使用默认的进行压缩

Manifest文件

首先简单的介绍一下里面的内容如图所示:

Asset:包中的内容(图中显而易见是一个预制体)。
Dependencies:依赖(地址)。

其作用是用unity读取该文件来获得该物体所使用的依赖,如果在使用该物体时依赖的包还没有被加载则显示材质丢失,如图:

通过AssetBundle的Manifest文件的到某个包的依赖
   //参数:文件夹/文件(这个文件是根据文件夹自动生成的所以名字相同)
    AssetBundle manifestAB = AssetBundle.LoadFromFile("AssetBundles/AssetBundles");
    AssetBundleManifest manifest = manifestAB.LoadAsset<AssetBundleManifest>("AssetBundleManifest");

    测试1:取得所有包名
    //foreach (string name in manifest.GetAllAssetBundles())
    //{
    //    print(name);
    //}

    ///取得某个包的依赖
    //获取cubewall里面的所有的依赖
    string[] str = manifest.GetAllDependencies("cubewall.unity");
    foreach (string name in str)
    {
        AssetBundle.LoadFromFile("AssetBundles/" + name);   //加载出来所有的依赖包
    }

加载AB包和包里面的资源

简单的介绍一下AssetBundle的使用,大概分为以下四种:
1. AssectBundle.LoadFormMemoryAsync 从内存中加载(Async异步,不带则是同步。)
2. AssectBundle.LoadFormFile 直接从本地文件加载
3. WWW.LoadFormCacheOrDownload 可以从本地/服务器加载(在unity2017之后就不经常使用,可能被弃用使用一下的方式)
4. UnityWebRequest (Unity5.3及以上才可使用) 非常明确就是从web加载

这四种都是静态方法

四种方式实现的方法:

    /// <summary>
    /// 第一种:从内存中加载(异步/同步)
    /// </summary>
    AssetBundleCreateRequest request = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(path));
    //等待加载完成
    yield return request;
    AssetBundle ab = request.assetBundle;

    AssetBundle ab = AssetBundle.LoadFromMemory(File.ReadAllBytes(path));



    /// <summary>
    /// 第二种:从本地上加载(异步/同步)
    /// </summary>
    AssetBundleCreateRequest request = AssetBundle.LoadFromFileAsync(path);
    yield return request;
    AssetBundle ab = request.assetBundle;

    AssetBundle ab = AssetBundle.LoadFromFile(path);




    /// <summary>
    /// 第三种:WWW (这个也需要使用协程)
    /// 可以从本地也可以从服务器
    /// 如果从本地把地址前加“file”
    /// </summary>
    while (Caching.ready == false)
    {
        yield return null;
    }
    //返回的www对象,参数为(地址,版本号)
    WWW www = WWW.LoadFromCacheOrDownload(wwwPath, 1);
    //如果是空字符串,空对象都是没有错误的
    if (string.IsNullOrEmpty(www.error) == false)
    {
        Debug.Log(www.error); yield break;   //因为www出现错误不会出现异常而是继续运行,所以要先判断一下。
    }
    AssetBundle ab = www.assetBundle;



    /// <summary>
    /// 第四种:使用UnityWebRequest
    /// using UnityEngine.Networking;
    /// </summary>
    UnityWebRequest request = UnityWebRequest.GetAssetBundle(webPath);
    yield return request.SendWebRequest();        //等待下载完成
    //加载的两种方式
    AssetBundle ab = DownloadHandlerAssetBundle.GetContent(request);
    //AssetBundle ab = (request.downloadHandler as DownloadHandlerAssetBundle).assetBundle;

注意本地的地址写法:`file:// file:/// 都是可以的

    string wwwPath = @"file:///E:\UnityProject\Study\AssetBundle_Text\AssetBundles\cubewall.unity";`  

四种我读的都是本地,服务器基本是一样的,修改地址即可。

AssetBundle的卸载

减少内存的使用

如果卸载不当则会导致材质的丢失。所以根据以下判断:
AssetBundle.Unload(true):
卸载所有的资源,即使资源被使用着(如:在关卡切换、场景切换。 资源没被使用的时候)。
AssetBundle.Unload(true)
卸载所有没有被适应的资源(通过“Resources.UnloadUnusedAssets.”)。

推荐学习/参考网站:Unity

知识共享许可协议
本作品由A_AiTing采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值