【Unity】AssetBundle和AssetBundle Manager的使用和介绍(流程和依赖关系)

mahua

AssetBundle and the AssetBundle Manager

介绍

AssetBundle允许从本地或者远程服务器加载Assets资源,利用AssetBundles技术,Assets资源可以放在远程服务器上,这种技术增加了项目灵活性并且减少项目初始包的大小。

本文介绍AssetBundles并且讨论一步一步的介绍怎么样使用它,怎样将资源打包到AssetBundle中,如何使用以及如何处理资源的引用计数,所有这些我们都可以使用AssetBundle Manader来简化AssetBundle构建、测试和发布环节。最后会介绍一个使用AB和Variants实际项目的例子。

示例

在读本文开始之前,最好先从官方下载下载示例

什么是AssetBundle

AssetBundles是Unity编辑器中在编辑过程中创建的一些文件,这些文件可以在项目运行环境中使用。AssetBundles可以包含的资源文件比如模型,材质,贴图和场景等等,注意:AssetBundles不能包含脚本!

具体来说,一个AssetBundle就是把资源或者场景以某种方式紧密集合在一起的一个文件。这个AssetBundle文件可以被单独加载到unity应用程序中。这允许模型、贴图、音效设置很大的场景这些资源进行流式加载或者异步加载。当然AssetBundle文件也可以本地缓存这样能够在程序启动的时候立马被加载出来。但AssetBundle技术主要目的就是需要的时候从远程服务器下载需要的资源。AssetBundle可以包含任何unity可识别的资源文件,甚至包括二进制文件。但就是不能包含脚本文件。

有很多AssetBundle的使用案例。资源在程序中可以被加载和释放。Post-release DLC可以被轻易的实现。应用程序发布的时候可以使得包体变得更小,在应用程序启动的时候加载需要加载的资源。应用程序国际化也会变得相对简单,我们可以根据玩家的地理位置来判断加载对应的资源文件。应用程序可以用新的资源文件来达到修复、更新的目的。

AssetBundles怎么管理和规划更取决于具体的项目需求。以下有一些基本的规则以便我们更好的理解AssetBundle。 
* AssetBundle需要整体的下载和缓存的 
* AssetBundle不需要整体的加载到应用程序中 
* Assets在AssetBundles中是具有相互依赖性的 
* Assets在AssetBundle中可以和其他资源共享依赖 
* 每一个AssetBundle都有一些技术开销,在文件加载上和对文件的管理上 
* AssetBundle必须针对平台进行打包

每一个AssetBundle都是被整体下载的,就算它不会立马被用到甚至不会在当前场景中用到,它也会占用下载和磁盘空间资源。

一个AB文件被整体下载之后,我们可以根据需要去加载里面的资源。

一个资源可能会对其他资源有依赖关系,比如一个模型可以有很多依赖关系,一个游戏中的模型不仅仅只有网格数据,实际上他是一个拥有很多依赖资源组成的一个共同体。 
tank 
一个网格模型及其所使用的材质

这个坦克模型的Mesh Render依赖材质资源,材质又依赖贴图资源。因此这个坦克模型依赖三个文件资源并不是仅仅就一个网格资源

tank
这个坦克模型的资源依赖链:模型 > 材质 >纹理

Assets资源之间也是可以相互依赖的,例如:两个不同的模型可以共享相同的材质,这个材质是依赖贴图资源。 
tank 
不同的岩石模型共享相同的材质

在组织AssetBundle结构的时候,需要去平衡开销,把AssetBundle分成若干个很小的AssetBundle的时候会很耗性能,但如果做成一个大的AssetBundle又会包含许多不需要用到的资源,所以要根据你实际的项目来平衡。

AssestBundle的目录被以优化的方式编译到目标平台上根据目标平台的导出设置,因为这样所以AssestBundles需要导出到各个目标平台。

依赖关系和依赖管理

关于依赖和依赖管理有几个重要的点

资源依赖永远不会丢失。如果这个依赖的assest在AssestBundle被创建时没有指定任何的AssestBundle,依赖的Assest连同选中的Assest将被添加到AssestBundle,这是非常方便和避免依赖Assest的损失。但是这也可能导致Assets重复。例如,使用两个岩石上面共享相同的Material,如果岩石列在单独的AssetBundles和Material没有显式地指定一个AssetBundle,将被添加到包含那种Material的两个 AssetBundles包中。值得注意的事,当这么做的时候,两个重复的资源将被存储在各自的AssetBundles而且依赖关系也破裂了,每个模型的Assest将依赖自己复制出来的Material,没有了共享Assest的任何优势。为了防止这种情况的发生,这些材料需要显式地指定一个AssetBundle,这可以实现对自己和其他资源的分享。用这种方法,这两个岩石的AssestBundle将依赖这个岩石Material。

关于依赖信息都存储在Mamnifest文件中,这个文件很像AssetBundle的资源的table文件。当AB构建时,unity统一生成大量数据,这些数据保存清单的细节,每一个目标平台都有一个对应的清单,清单列出所有为当前平台所需要的AssetBundles存储,跟踪和依赖项。使用清单可以查询所有AssetBundle和他们的依赖项。

有一个关于AssetBundles的特别的设置被叫做 AssetBundle Variants,AssetBundle Variants目的在于一种特殊的情况:在项目中重新映射一个不同Assest中的单个对象,这对于一个需要基于标准分辨率、语言、定位、或用户偏好选择不同的Assest特别有用。 AssetBundle Variants可以容纳所需的各种Asset的覆盖所有支持选择对象和所需的Asset可以根据需要被映射到该对象的选择的AssetBundle Variants。

AssetBundles文件包含资产文件,如模型、材料、材质和场景。AssetBundles在辑器编辑创建在游戏中使用,AssetBundles旨在从本地或远程加载资源。AssetBundles可以变异映射到对象根据现场用户的偏好。

Working with AssetBundles and the AssetBundle Manager

介绍

对于使用AssetBundles的一个关键和重要的工作是对Asset构建测试,通常,AssetBundles会定期的发生改变,所以需要定期的创建AssetBundles,然后将其上传到一个远程服务器并测试托管的AssetBundles资源。

本章重点介绍使用AssetBundles Manader。AssetBundle Manager提供了一个高级的API大大提高了工作流。

使用AssetBundles

使用AssetBundles有以下几步: 
* 在编辑器里面构建AssetBundles 
* 上传AssetBundles到外部存储 
* 在运行时下载AssetBundles 
* 从AssetBundles中加载物体 
值得注意的是一些AssetBundles可以存储在本地,以保证立即加载,这有助于防止一个应用程序的安装不能从远程下载所有的AB资源。例如,当应用程序没有访问下载内容时将从本地AssetBundles加载默认语言和本地数据。

值得注意的是,一个AssetBundles会根据平台进行打包,AssetBundles根据导入的设置和目标平台中的设置构建为目标平台的AB资源。

在下面的场景中,一种方式就是打包包括地面,沙丘,岩石,仙人掌,树。这些场景允许包括所有独立的材质。坦克模型会有自己的AssetBundles,这样允许改变或者更新玩家信息。想要完成这个坦克的GameObject创建,需要额外依赖两个AssetBundle一个是材质球,一个是纹理,这么做对于更新这个材质球和纹理来说,将会造成最小的麻烦,也允许选择版本或者多个版本,从多个版本中选择一个需要的AssetBundle来实现平台,国际化或者目标设备的区分。 
tank
一个简单的场景

在Editor模式下组织和构建AssetBundles,资源必须分配给一个AssetBundle,当查看一个资源,在Inspector面板中右下角可以看到这个AssetBundle的名字和Variant。预览窗口打开才能看到。 
tank 
还没有分配的坦克资源

使用AssetBundle名称下拉菜单进行分配资源,在这里要不选择一个现有的要不创建一个新的。 
tank 
分配一个资源到AssetBundle

创建一个新的AssetBundle,选择New并且文本输入框就会有效让你输入名字 
如果要移除一个资源,只要选择None就可以 
如果想从列表中删除一个AssestBundle名字,那必须要把所有的分配给这个AssestBundle的资源的名字都从AssestBundle中删除掉。然后可以选择Remove Unused Names,将删除所有没被使用的AssestBundle的名字。 
tank 
AssetBundles名字必须小写,如果不遵循的话,unity会自动处理成小写。 
tank 
这样AssetBundles名字就被强制改成了小写。

使用AssetBundles Variants

允许以各种不同的解决方案解决加载问题,包括下载、存储和更新,一种特定的情况就是AssetBundle 可以依据设备来加载不同的用户偏好等,这是利用AssetBundle Variants。对场景中的一个物体上同一个资源AssetBundle Variants提供不同的Variants,AssetBundle Variants可以实现替换不同的资源到同一个物体上,只有一种Variants可以在任何时间进行加载。

AssetBundle Variants在很多情况上多可以使用,AssetBundle Variants可以为不同分辨率的机器或者高低显卡配置不同的机器或者不同面数的多边形提供相同的资源,AssetBundle Variants可以根据文本、图像、纹理和字体可以为每个受支持的语言不同,地区或主题创建不同的对象。这些资源保存了一系列信息。

以下是AssetBundle的小例子 
tank 
tank 
tank 
在上面例子中,两个文件夹MyAssets-SD和HD同时被分配到myassets的AssetBundle,然后得到一个是别名分别是hd和sd,注意这两个资源具有相同的名称和结构,在创建一个资源的时候父目录被指定到一个AssetBundle上,没有被指到任何一个AssetBundle上。

值得注意的是下面的图片的AssetBundle有一个路径variant/myassets 
tank 
这将为名叫myassets的AssestBundle创建一个父菜单,叫variant。一旦一个资源被分配好了之后需要被打包和测试。

未完,待续。。。

友情提醒

新手翻译,翻译不对之处多多见谅!

参考链接

关于译者

  var aladdin = {
    nickName  : "Aladdin",
    site : "http://blog.csdn.net/dingxiaowei2013"
    u3d QQ Group :159875734
  }
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

更多关于AB的优质文章和参考

  • 3
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
AssetBundle 引用计数是指在使用 AssetBundle 打包资源的时候,记录每个 AssetBundle使用的次数,以便在使用完后及时释放资源,从而避免内存泄漏。在使用 AssetBundle 加载资源时,会对加载的 AssetBundle 进行引用计数的增加,使用完后再进行引用计数的减少,当引用计数为 0 时,就可以释放该 AssetBundle 的资源。 AssetBundle 的打包和加载一般分为以下几个步骤: 1. 打包资源文件:使用 Unity Editor 自带的 AssetBundle 打包工具,将需要打包的资源文件进行打包,生成 AssetBundle 文件。 2. 加载 AssetBundle 文件:在游戏运行时,使用 Unity 提供的 AssetBundle.LoadFromFile 或 AssetBundle.LoadFromMemory 函数来加载 AssetBundle 文件。 3. 加载资源文件:使用加载的 AssetBundle使用 AssetBundle.LoadAsset 或 AssetBundle.LoadAssetAsync 函数加载需要使用的资源文件。 4. 使用完成后,释放资源:使用 AssetBundle.Unload(false) 函数来释放 AssetBundle 中的资源,同时进行引用计数的减少。如果不再需要该 AssetBundle 中的任何资源,可以使用 AssetBundle.Unload(true) 函数来彻底释放该 AssetBundle,包括清除 AssetBundle 的缓存。 使用 AssetBundle 打包和加载资源可以有效地减少应用程序的内存占用,提高应用程序的性能。同时,在使用 AssetBundle 的时候,需要注意避免重复加载同一个 AssetBundle,以及及时释放不再使用的 AssetBundle 资源,避免内存泄漏。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值