Unity3dAssetBundle

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

一、什么是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贴图。

img_4934ef24c54d2f773d771dcb40e0399f.jpe
img_eea0268adc51151e38e65d71ed811789.jpe

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

img_edea4d5d24bbcb6d328bfacaabd43f43.jpe

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

img_34672fbecfaac1261c8551a9ac091245.jpe

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

img_0411fe9bb2eed08e8945f39779b7d1fd.jpe

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

img_3394c77597589a8380505b9ee4e9479b.jpe

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

再看看obj1.ab.manifest

img_f8be2e9963db637560f4eae3e5f44ac7.jpe

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

接下来把obj2也赋予AssetBundleName:

img_8b5ee9f78a4858f53f859bfa277977fd.jpe

再导出,会发现除了刚才的文件以外,会多了2个文件,就是obj2.ab和obj2.ab.manifest。

还是打开AssetBundle.manifest看看,会发现

img_5ba2e7b189494ded9359f313c016602b.jpe

这次的Info变成了2个,分别是obj1.ab和obj2.ab

打开obj1.ab.manifest

img_f2fa116503fcb1152e2aafa91db31a95.jpe

发现和刚才没什么变化。

再看看obj2.ab.manifest

img_aefc6ada0a6f681dcbb97878aa2daca2.jpe

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

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

不厌其烦的把图贴上来:

img_1aa12aaa5fe644dd4f7a0c784e9ff045.jpe
img_f23e45efdbca60aabbbeee2cc2087809.jpe
img_b42ba704290e34c4c6def9cf80c141db.jpe
img_cc903083e51f2b4aaa982cb08e1c8eaf.jpe
img_4fb392e709d90f9e535136bb53ed2556.jpe
img_1165f67de9ec96902be7ec6732ff9c34.jpe

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

img_1e1d0bfa5e0bb9a6df0c1449bee00be7.jpe

再来看AssetBundle.manifest

img_c7d9dc8987f34c9439a59b04b6c737c2.jpe

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

看obj1.ab.manifest

img_97caee5a4be4e42ab54c3cbf94f133ce.jpe

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

看m1.ab.manifest

img_36b074cd31d72f165212d3edc83b998c.jpe

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

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

img_6d9621c12c3e6bbc92ccd8daf3a585b7.jpe
img_99f983baecfc821c074933037082121d.jpe

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

img_8a1279d6c7e8e4c767f60e31f1d06186.jpe

那么现在我们再整个项目的AssetBundle导出,会怎样?

导出完之后,看目录,会发现文件和刚才是一样多的,t4.ab并没有被删掉。

再看AssetBundle.manifest

img_606718efe8091ee391b0858d76c23bd5.jpe

Info变成6个了,而里面某些项的依赖列表变了

看obj1.ab.manifest

img_582ef0cc71edc406aa7027bc7ac6ee29.jpe

和刚才没有变化

看obj2.ab.manifest

img_7c59eeb970b0c8775b60b7c873f2a3a2.jpe

和刚才也是没有变化的

看m2.ab.manifest

img_d9716a7ed91dc15b7042f1d8fc9480e2.jpe

这里的依赖列表没有了。

这其实就是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就行了

img_699418617a86c3afab68973ee879cb6d.jpe

四、加载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加载完之后,你爱怎样用都可以,直接实例化出来吧。

img_92e0bb66c7467a0ec672eb0919d7676b.jpe

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

相关实践学习
Serverless极速搭建Hexo博客
本场景介绍如何使用阿里云函数计算服务命令行工具快速搭建一个Hexo博客。
相关文章
|
5月前
|
编解码 算法 图形学
【unity小技巧】减少Unity中的构建打包大小
【unity小技巧】减少Unity中的构建打包大小
127 0
|
6月前
|
缓存 API 图形学
【Unity 3D】AssetBundle打包、上传、加载、卸载详解及演示(附源码)
【Unity 3D】AssetBundle打包、上传、加载、卸载详解及演示(附源码)
233 0
|
6月前
|
算法 图形学 UED
【Unity 3D】AssetBundle工作流程、打包策略详解(超详细必看)
【Unity 3D】AssetBundle工作流程、打包策略详解(超详细必看)
371 0
|
Java 图形学
[unity]Unity3d获取APK签名及公钥的方法
在Unity3d项目中获取APK包签名公钥的方法,核心思想就是通过JNI调用Android提供的方法。不过Unity3d提供了比JNI更上一层的类AndroidJavaObject以及继承它的AndroidJavaClass,帮助开发者省去很多工作。
1721 0
|
图形学 索引
|
存储 缓存 API
5.0版本之后的AssetBundle资源的打包和解析加载(Unity3D)
这几天在研究AssetBundle资源打包盒解析加载,也踩过很多坑,参考过很多人的文章 发现很多人关于AssetBundle的文章不是API过时了不能用,就是有点乱 也不是有点乱,就是摸不着头脑,让人不能快速的get到这个东西如何使用 所以我特意在踩过坑之后把我这个学到的经验分享给大家。
|
XML 图形学 数据格式
Unity3d游戏开发之使用AssetBundle和Xml实现场景的动态加载
在Unity3D游戏开发过程中,因为受到游戏容量、平台性能和热更新等诸多因素的限制,我们可能无法将所有的游戏场景打包到项目中然后相对”静态”地加载,那么这个时候就需要我们使用动态加载的方式来将游戏场景加载到场景中。
1313 0
|
XML Java Android开发
Unity是怎么打包APK文件的
大家看过一些第三方组件的接入文档都知道,在Unity里面有几个特殊的文件夹是跟打包APK有关的。首先我们就来了解一下,这些文件夹里面的内容是经历了哪些操作才被放到APK里面的呢? 在Unity的Assets目录下,Plugins/Android无疑是其中的重中之重,首先我们先来看一个常见的Plugins/Android目录是什么样子的。
5224 0
|
图形学 UED
Unity打包/读取AssetBundle资源全教程
Unity 资源AssetBundle打包 本文提供全流程,中文翻译。 Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 —— 高分辨率用户请根据需求调整网页缩放比例) Chi...
2204 0