一、什么是AssetBundle

估计很多人只知道Unity的模型之类的东西可以导出成一种叫做AssetBundle的文件,然后打包后可以在Unity程序运行的时候再加载出来用。那么AssetBundle是一个什么样的东西呢?

其实AssetBundle只是一种使用LZMA压缩方式压缩的资源文件。具体LZMA是什么请百度,你可以理解成就是一种压缩文件就行了,至于它的后缀名是什么,一点关系都没有,你可以自己定。

AssetBundle打包的时候,你可以指定一个mainAsset,那么加载完之后就可以通过AssetBundle.mainAsset来获取到了。你也可以不指定mainAsset,直接打包一堆内容进去,然后加载后通过AssetBundle.LoadAsset指定名字的读取出来。在资源之间,存在着依赖的关系。你可以把资源拆分得很细,比如一个模型,由网格模型、材质、贴图构成,你可以把每一个小部分都拆开,各自打包成压缩文件。当Unity需要加载使用的时候,把该模型所有依赖的小资源都加载出来,然后根据依赖关系组装,就变回了我们看到的资源了。

二、AssetBundle的依赖结构

要说明依赖关系结构,我们还是使用上面的例子,一个模型,分为了网格模型、材质、贴图。那么他们是怎样依赖的呢?然后在Unity5的打包里面,他们是怎样表现出依赖关系的呢?

接下来做一个小小的实验:我准备了4张贴图,分别叫做t1、t2、t3、t4,然后建立了两个材质球,分别是m1、m2,m1材质使用了t1、t2、t3三张贴图,m2材质使用了t4贴图。

最后建立两个模型,我就使用unity内置的模型了。obj1是一个cube,obj2是一个quad。obj1使用了m1材质,obj2使用了m2材质。然后obj1和obj2都做成了预设,放在了Assets/Resources/Obj下面。

那么现在他们的结构应该是这样的:

接下来,先只设置obj1的assetBundleName,然后导出

导出之后,我们看看AssetBundle.manifest:

里面只有一个Info,就是刚才我们命名的obj1.ab,而obj1.ab下面的Dependencies是空的,也就是它没有任何依赖了。

再看看obj1.ab.manifest:

它里面包含了类型的哈希码、Assets资源的路径,和依赖。这里它的依赖还是空的。

接下来把obj2也赋予AssetBundleName:

再导出,会发现除了刚才的文件以外,会多了2个文件,就是obj2.ab和obj2.ab.manifest。
还是打开AssetBundle.manifest看看,会发现这次的Info变成了2个,分别是obj1.ab和obj2.ab

打开obj1.ab.manifest发现和刚才没什么变化。

再看看obj2.ab.manifest:

它的结构和obj1.ab.manifest差不多。

刚才只是把2个模型设置了导出AssetBundle,接下来把两个材质和四张贴图都设置导出:

  

这时候导出,我们的所有依赖关系都应该存在了。导出之后,多了很多文件,是这样的:

再来看AssetBundle.manifest:

这次看到的Info有7个了,其实我们设置了多少个AssetBundleName导出,它就应该有多少个Info。

看obj1.ab.manifest:

这次看到它的Dependencies,会看到有依赖了,写的是一个本地的地址。有人会说,这个绝对路径有问题啊,我把这个文件放到cdn上面,路径就会不对啊。这个先不急,下面会说明是什么回事。
看m1.ab.manifest:

会发现结构差不多,但依赖列表里面会有三个地址,就是我们三张贴图的地址了。

看obj2.ab.manifest 和 m2.ab.manifest情况会差不多

接下来,要做最后一步试验了,比如刚才我已经是整个项目的导出了,现在我突然需要改动其中的一个小部分,t4就不导出了。

那么现在我们再把整个项目导出,会怎样?导出完之后,看目录,会发现文件和刚才是一样多的,t4.ab并没有被删掉。再看AssetBundle.manifest

Info变成6个了,而里面某些项的依赖列表变了看obj1.ab.manifest和刚才没有变化

看obj2.ab.manifest和刚才也是没有变化的

看m2.ab.manifest这里的依赖列表没有了。

这其实就是AssetBundle的链式结构和增量打包了。一个小的部分改变了,它将会改变的地方只有总的AssetBundle.manifest,还有直接依赖于它本身的manifest。其他不依赖的部分是不需要重新打包的。还有一点需要注意的地方是,除了manifest文件以外,还有一个没有后缀名称的AssetBundle文件。这个文件其实才是包含了所有的依赖关系的总的依赖关系配置文件,刚才我们能用txt打开的manifest文件,都只是用来做本地依赖关系和增量打包的时候用的。我们加载AssetBundle的时候,完全不需要加载那些manifest文件的,只需要那个没有后缀名称的AssetBundle文件(具体名字和你导出的文件夹有关)就行了,它代表的是该项目的所有AssetBundle的依赖关系。所以,刚才我们看到manifest里面用的都是本地的绝对路径,那是针对你本地打包时用的,和加载无关。

三、导出AssetBundle和自动设置名称

刚才我们都是直接的输入AssetBundleName来导出AssetBundle的,其实这一步可以使用代码自动完成在Unity项目内部,每一个小的资源(网格、材质、贴图、声音等),都会有一个唯一的哈希Id的,是一串很长的字母和数字组合。我们可以通过AssetDatabase.AssetPathToGUID来获得这个ID。那么自动设置就变得简单了,可以通过以下的代码,我们可以设置一个总的prefab的AssetBundleName,然后自动获得它身上的所有依赖,然后获得每个依赖资源的唯一Id,再赋予AssetBundleName就行了

四、加载AssetBundle的步骤

通过上面导出AssetBundle的说明,估计现在想要把它加载起来就变得简单了。

首先需要明白一个规则,资源的依赖关系组装是unity本身会自动完成的。比如一个资源A,它是依赖于资源B和资源C的,那么如果我们需要加载资源A进来并正确的显示出来,我们必须先把资源B和资源C加载,然后再加载资源A。当资源A加载进来之后,发现内存里面已经有资源B和资源C了,它会自动的组装起来。

那么再看看加载的步骤了:

1、获得总的依赖配置刚才已经说明了,真的有用的依赖配置文件是没有后缀名称的AssetBundle文件,所以我们需要加载的就是这个文件了。string
mUrl = Cdn +
"AssetBundle";然后www加载。之后很多人看不懂,说我这个Cdn是什么东西,“AssetBundle”又是什么东西,现在应该明白了吧?Cdn就是你的资源服务器路径,“AssetBundle”就是文件名,它没有后缀,具体的名字是和你导出的文件夹一样的。加载后,通过AssetBundle.LoadAsset("AssetBundleManifest"),就可以把刚才那个没有后缀名的文件转成AssetBundleManifest对象mainfest。

2、根据名称找到目标加载资源的所有依赖获得了AssetBundleManifest对象mainfest之后,比如我们实际上是需要加载obj1.ab的,这在刚才的AssetBundle.manifest里面可以知道,它的Info里面就有obj1.ab。然后我们通过string[]
dps =
mainfest.GetAllDependencies("obj1.ab");就可以获取到obj1.ab的所有依赖了,包括了子依赖,比如它依赖于m1.ab,然后m1.ab依赖于t1.ab、t2.ab、t3.ab,那么这里获取到的就应该是4个依赖了。分别是m1.ab、t1.ab、t2.ab、t3.ab。

3、加载所有依赖的资源获取到obj1.ab的所有依赖之后,就应该逐个的去加载他们了。分别www加载他们,然后保存他们的AssetBundle。

4、加载目标加载资源当加载了所有的依赖资源之后,就可以光明正大
的去加载目标资源了,这里我们的目标资源就是obj1.ab。

5、实例化显示obj1.ab加载完之后,你爱怎样用都可以,直接实例化出来吧。

由于AssetBundle是不能重复加载的,如果你需要多次加载一个资源,你有2个选择,要么加载了就Unload(false)卸载了它。要么你可以把它存起来,当需要相同名字的AssetBundle的时候,直接取出来。

五、最后的建议

1、Unity5的新版AssetBundle好像是一套全新的系统,其实和旧系统的差别并没有很大,只是自动生成了依赖配置文件而已。这一个步骤实际上完全可以自己实现的,那些配置文件可以用自己喜欢的格式生成,然后加载的时候再自己想办法把依赖关系找回来就行了。

2、个人觉得把AssetBundle拆得太碎并不是一件好事情。为什么这么说呢?用过电脑的人都知道,拷贝文件的时候是一个个碎的文件拷贝快?还是把一堆文件压缩成一个包,然后拷贝快?如果加载一个模型,需要分别加载十几次依赖资源,才能显示,这个过程中发送这么多的www或者http请求,过程有点危险。至于说冗余文件的问题,自己考虑一下分布策略吧。

Unity5.X 新版AssetBundle打包控制的更多相关文章

  1. Unity5.x版本AssetBundle打包研究

    Unity5的AssetBundle打包机制和以前版本不太一样.简单的说就是,只要给你要打包的资源设置一个AssetBundleName ,Unity自身会对这些设置了名字的资源进行打包,如果一个资源 ...

  2. Unity5.X 新版AssetBundle使用方案及策略

    1.概览 Unity3D 5.0版本之后的AssetBundle机制和之前的4.x版本已经发生了很大的变化,一些曾经常用的流程已经不再使用,甚至一些老的API已经被新的API所取代. 因此,本文的主要 ...

  3. Unity5.4新版AssetBundle资源打包

    (1)新版本 唯一打包API Buildpipeline.BuildAssetBundle (2)在资源的Inpector界面最下方可设置该资源的assetbundleName, 每个assetbun ...

  4. Unity5版本的AssetBundle打包方案之打包Scene场景

    using UnityEngine; using System.Collections; using UnityEditor; /// <summary> /// 脚本位置:Editor文 ...

  5. Unity5系列资源管理AssetBundle——打包

    资源管理是游戏开发的重要环节,Unity中使用AssetBundle可以非常方便地帮我们打包和更新游戏内容,在5系列中,AssetBundle更是方便好用,现在让我们先进行打包吧. 刚说了,5系列打包 ...

  6. unity-------------------Unity5.X 新版AssetBundle使用方案及策略

    Unity5.X 新版AssetBundle使用方案及策略   1.概览 Unity3D 5.0版本之后的AssetBundle机制和之前的4.x版本已经发生了很大的变化,一些曾经常用的流程已经不再使 ...

  7. Unity5.x版本AssetBundle加载研究

    之前说了 “Unity5.x版本AssetBundle打包研究”,没看过的请先看一下:http://www.shihuanjue.com/?p=57 再来看本文,有一定的连接性. 先梳理一下思路: 要 ...

  8. [Unity] unity5.3 assetbundle打包及加载

    Unity5.3更新了assetbundle的打包和加载api,下面简单介绍使用方法及示例代码. 在Unity中选中一个prefab查看Inspector窗口,有两个位置可以进行assetbundle ...

  9. Unity5 AssetBundle打包加载及服务器加载

    Assetbundle为资源包不是资源 打包1:通过脚本指定打包 AssetBundleBuild ab = new AssetBundleBuild                         ...

随机推荐

  1. RootMotionComputer 根运动计算机

    using UnityEngine; using System.Collections; /* * -------------------------------------------------- ...

  2. python发送邮件实例1

    文件形式的邮件 #!/usr/bin/env python3 #coding: utf-8 import smtplib from email.mime.text import MIMEText fr ...

  3. 利用JqGrid结合ashx显示列表之一

    最近项目决定运用JqGrid列表控件显示相关数据,以前接触比较多还是easyui和Ext.Net的列表控件,文章简单写的小实例进行一个总结: 1:引入相关的JS及CSS文件,JqGrid目前可以利用J ...

  4. Eddy&#39;s digital Roots

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission ...

  5. 转:发一个自己用过的makefile .

    #gcc test.cpp -L. -Wl,-Bdynamic -ltestlib -Wl,-Bstatic -ltestlib  -Wl,-Bdynamic #make clean; make in ...

  6. 【CentOS6.5】MySQL安装和配置

    1./etc/my.cnf 这是mysql的主配置文件 2.数据存放位置 3.错误存放位置

  7. IntelliJ IDEA类头注释和方法注释

    The template is editable. Along with static text, code and comments, you can also use predefined var ...

  8. AutoFac文档14(转载)

    目录 开始 Registering components 控制范围和生命周期 用模块结构化Autofac xml配置 与.net集成 深入理解Autofac 指导 关于 词汇表 激活事件 在compo ...

  9. MongoDB,还有一个角度看数据

    传智-玄痛(传智播客北京校区C/C++学院技术指导老师) MongoDB的起源 几年前 10gen 公司做了 SaaS 方面的研发,由于公司一个 MongoDB 产品存储接口的易用性,用户评价很好,公 ...

  10. union共用体的对齐

    union DATE { char a; ]; double b; }; DATE max; cout<< sizeof(max) << endl; 这个问题很好回答,并且我把 ...