AssetBundles and the AssetBundle Manager
Introduction
AssetBundles allow on demand streaming and loading of Assets from a local or remote location. With AssetBundles, Assets can be stored remotely and accessed as needed, increasing the flexibility of the project and reducing the initial application size.
This lesson will introduce AssetBundles and discuss how to work with them, the steps and stages of the AssetBundle workflow, how to assign Assets to an AssetBundle, how and when to use AssetBundle Variants, how to build and test AssetBundles and Variants - all in the context of using the AssetBundle Manager to simplify creating, testing and deploying AssetBundles. The final section of the lesson will cover specific examples of loading and using AssetBundles and AssetBundle Variants with simple use-cases and simple example scripts.
Sample Project
Before starting this Tutorial Article, it would be best to download the AssetBundle Manager with the AssetBundle Sample project here.
What is an AssetBundle?
AssetBundles are files created in the Unity editor during edit-time, which can be used later by a build of a project at run-time. AssetBundles can contain asset files such as models, materials, textures and scenes. AssetBundles cannot contain scripts.
Specifically, an AssetBundle is a collection of assets and/or scenes from a project saved in a compact file with the purpose of being loaded separately to the built executable application. AssetBundles can be loaded on demand by a game or application built in Unity. This allows streaming and asynchronous loading of content such as models, textures, audio clips, or even entire scenes. AssetBundles can be “pre-cached” and stored locally for immediate loading when first running an application. The primary purpose of AssetBundles, however, is to stream content on demand from a remote location, to be loaded into the application as necessary. AssetBundles can contain any kind of asset type recognized by Unity, including custom binary data. The only exception is that script assets are not allowed.
There are many use-cases for AssetBundles. New content can be dynamically loaded and unloaded from an application. Post-release DLC can easily be implemented. An applicationrsquo;s disk footprint or size can be reduced when first deployed, with assets being loaded after installation of the application and only as the assets are needed. Platform and device specific assets can be loaded without having to download or store redundant assets for other platforms or resolutions. Localization of applications becomes easy by downloading and installing only the assets needed based on the userrsquo;s location, language or preferences. Applications can be fixed, changed or updated with new content without having to resubmit the application for approval.
The detailed organization of any projectrsquo;s assets into AssetBundles will be heavily dependent upon the needs of that particular project. There are, however, some basic tenets to understand about AssetBundles.
bull;AssetBundles are downloaded and cached in their entirety.
bull;AssetBundles do not need to be loaded in their entirety.
bull;Assets in AssetBundles can have dependencies on other assets.
bull;Assets in AssetBundles can share dependencies with other assets.
bull;Each AssetBundle has some technical overhead, both in the size of the file and the need to manage that file.
bull;AssetBundles should be built for each target platform.
AssetBundles are downloaded in their entirety. If an AssetBundle contains Assets that are not immediately needed, even though they wonrsquo;t necessarily be loaded into the scene, they will take up both bandwidth to download and disk-space to store.
The contents of AssetBundles do not need to be loaded in their entirety. Once an AssetBundle has been downloaded, Assets can be selectively loaded from the AssetBundle.
Assets can have dependencies on other assets. For example, a model can have several dependencies. The final model in the game is not just mesh data, but it is a GameObject with all of its Components and all of the Componentrsquo;s dependencies.
descriptionA Mesh Model, with Material applied
This model is dependent on a Material Asset in the modelrsquo;s Mesh Renderer, and that Material Asset is dependent on a Texture Asset for the Materialrsquo;s Albedo Texture. As a matter of fact, this tank is dependent upon three Materials, not just one.
descriptionThe tank modelrsquo;s Asset dependency chain: Model gt; Material gt; Texture
Assets can share dependencies with other assets. For example, two different models can share the same Material, which in turn could be dependent on a Texture.
descriptionBoth rock columns are different models that share the same Material
Each AssetBundle has some technical overhead. AssetBundles are files that wrap Assets. This wrapper adds to the overall size of the AssetBundle. Even though this is not a significant increase in size, it is measureable. AssetBundles also require a certain amount of management to organize, create, upload and maintain. The more AssetBundles being used increases overhead for a project, both technical and managerial.
When organizing AssetBundles, a balance must be struck between too many small AssetBundles that need to be tracked and generate overhead, and too few AssetBundles that are large and contain unnecessary or redundant data. The exact balance will depend heavily upon the needs of the project.
The contents of an AssetBundle are compiled and optimized for the current target platform according to the Import Settings and the current Target Platform. Because of this, AssetBundles shou
剩余内容已隐藏,支付完成后下载完整资料
介绍
AssetBundles 允许从本地或者服务器按需指定和加载资源(Assets)。通过 AssetBundles 技术,资源可以存放在远端的服务器上,当游戏中需要使用它们时,再去按照需要去加载这些资源。这种技术增加了项目的灵活性,并且减少了应用程序的初始包的体积大小。
本文讲介绍 AssetBundles 技术,并且讨论如何去使用它,AssetBundles 工作流的步骤和阶段,如何将资源打包到 AssetBundle 中去,如何使用以及何时应该使用 AssetBundle Variants,如何构建和测试 AssetBundles 和 Variants。所有的这些,我们都可以使用 AssetBundle Manager 来简化AssetBundles 的创建、测试和发布环节。本文的最后一章我们将介绍一个使用 AssetBundles 和 Variants 的实际例子。
示例项目
在开始阅读这篇文章之前,你最好先把这里的 示例项目 中的 AssetBundle Manager 下载下来,我们会在后面的章节中用到它。
AssetBundle 是什么
AssetBundles 是有 Unity 编辑器在编辑环境中(enit-time)创建的一些列的文件,这些文件可以被用在项目的运行环境中(run-time)。 AssetBundles 可以包括的资源文件有模型文件(models)、材质(materials)、纹理(textures)和场景(scenes)。AssetBundles 不能包含脚本文件。
具体来说,一个 AssetBundle 就是把一系列的资源文件或者场景文件以某种方式紧密保存的一个文件。这个 AssetBundle 文件可以被单独加载到可执行的应用程序中。AssetBundles 可以由被 Unity 构建的游戏或者应用按需加载使用。这允许对像模型、纹理、音频、甚至是整个的游戏场景这样的资源进行流式加载和异步加载。AssetBundles 可以预缓存(pre-cached)和存储在本地,这样在运行时就可以立即加载它们。但是 AssetBundles 技术的主要的目的是在需要的时候能够从远端的服务器上按需请求特定的资源,并加载到游戏中。AssetBundles 可以包含 Unity 可以识别的任何类型的资源,包括自定义的二进制数据。唯一的例外是,脚本资源是不被允许的。
有很多 AssetBundles 的使用案例。新的内容可以被动态的从应用程序中加载或者卸载。Post-release DLC 可以被更容易的实现。一个应用程序的磁盘占用或大小可以再第一次发布时被减小,在程序被安装后,在按照需要加载必要的资源。平台和设备相关的资源可以被正确的加载,而不需下载和存储当前设备不需要的平台或者分辨率所对应的资源文件。国际化也变得很容易,只需要根据用户的地理位置、语言和偏好设置来下载需要的资源就可以了。应用程序可以不需要提交新的版本就可以做到用新的资源内容来修复、改变和更新。
应该怎样把一个项目的资源具体组成成 AssetBundles,这将严重依赖于具体项目的需求。但是下面这些基本的原则可以帮助我们更好的理解 AssetBundles。
- AssetBundles 是需要整体下载和缓存的。
- AssetBundles 不需要整体的加载到应用程序中,可以只加载其中的某些资源。
- 在 AssetBundles 中的资源对其他资源有依赖关系。
- 在 AssetBundles 中的资源可以同其他资源具有相同的依赖关系。
- 每个 AssetBundle 都有一些技术开销,即在文件的大小上,也在管理这些文件上。
- AssetBundles 应该为每个目标平台单独构建。
每一个 AssetBundle 都是被整体下载的。如果一个 AssetBundle 包含了一些不是被立即使用的资源,甚至它们都不会被加载到当前这个场景中,它们也会耗费下载时的带宽和存储时的磁盘空间。
AssetBundles 的内容不需要被全部加载到应用程序中。只要 AssetBundle 被下载下来了,不同的资源就可以按照需要选择性的被加载。
一些资源可能会对其他资源有依赖关系。比如,一个模型资源可以有几个依赖。一个游戏中的模型不只是有网格数据(mesh data),实际上它是一个拥有它所有 Components 的 GameObject,以及每个 Component 自己做依赖的依赖关系。
一个网格模型及其所使用的材质
这个模型在 Mesh Renderer 中依赖于一个材质资源,而一个材质资源的 Albedo Texture 属性又依赖于一个纹理资源。所以,实际上这个坦克的模型依赖于三个资源,而不只是一个。
这个坦克模型的资源依赖链:模型 gt; 材质 gt; 纹理
资源可以其他资源共享依赖关系。比如,两个不同的模型可以共享一个相同的材质资源,而这又有可能依赖于同一个纹理资源。
这两种岩石柱拥有不同的模型,但是共享相同的材质
每一个 AssetBundle 都有一些技术开销。AssetBundles 是一些封装资源的文件。这种封装会增大了 AssetBundle 的整体大小,尽管这种大小的增加不会太明显,而且是可测量的。AssetBundles 也需要一定的管理开销来组织、创建、上传和维护。 在项目中使用越多的 AssetBundles 也会越多的增加这种开销,即包括技术开销也包括管理开销。
当组织 AssetBundles 时,是更多的小的 AssetBundles 还是更少的大的 AssetBundles 呢?这是需要我们根据自己的项目的实际情况来好好权衡的。更多的小的 AssetBundles 会面临更多的跟踪和创建相关的开销,太少的 AssetBundles 会使单个AssetBundle 本身的大小变大,也会导致它们可能包含一些冗余的数据。
由于 AssetBundle 的内容是按照当前的目标平台和它的 Import Setting 来构建和优化的,所以 AssetBundles 需要在每一个平台上单独构建。
MANIFESTS 和依赖管理
关于依赖关系和依赖管理,有几个要点是需要重点理解的。
资源的依赖关系是永远不会丢失的。如果当前选择的资源所依赖的其他资源没有被包含在任何一个 AssetBundle 中时,这些被依赖的资源就会被自动添加到当前的这个 AssetBundle 中。这是非常便利的,也防止依赖资源的丢失。但是,这也会导致资源的重复。比如,上面介绍的两个岩石柱的例子中,如果两个岩石柱在不同的 AssetBundle 中,并且它们共享的材质都没有被显示的指定到一个 AssetBundle 中去,那么这个材质就会被两个岩石柱的 AssetBundles 都重复包含进去了。值得注意的是,当这种情况发生时,所有重复的资源会保存在它们单独的 AssetBundles 中,并且现在它们的依赖关系就被打破了。每一个岩石模型资源现在都依赖于它们 AssetBundle 中的材质资源,这样就不再享有共享材质资源所带来的好处。为了防止这样的事情发生,材质就需要显示的指定到一个 AssetBundle 中去。这个 AssetBundle 可以是独立的,也可以和其他资源共享一个 AssetBundle。不管是哪一种方式,这个岩石柱的 AssetBundle 就要依赖于包含这个岩石柱材质的 AssetBundle。
一个工程的 AssetBundles 的依赖信息和其他信息被存储在一个 Manifest 文件中。这个 manifest 文件很像一个项目的 AssetBundles 内容的清单列表。当构建 AssetBundles 时,Unity 会产生很多数据。这些数据的详细情况被存储在 Manifest 中。每一个平台都会创建一个 Manifest。这个 Manifest 列出了这个工程根据当前的编译平台创建出来的所有的 AssetBundles,并且存储和跟踪他们的依赖关系。通过这个 Manifest,就能够查询所有的 AssetBundles 和他们的依赖关系。
对于 AssetBundles 还有一个特殊的操作,我们称之为 AssetBundle Variants。AssetBundle Variants 是为了满足一种特殊的用户需求而设计的:重新映射不同的资源到项目中的独立的物体上。当我们需要根据分辨率、语言、地理位置或者是用户的偏好设置来选择不同的资源时,这种技术就会非常有用。AssetBundle Variants 可以包含所有需要支持的资源,并能根据用户的具体选择来映射特定的资源到需要的对象上去。
其实说白了过程就是先扫描所有要打包的资源,然后用AssetDatabase.GetDependencies获得所有的依赖,自己记录起来,由于怕资源之间有重名的,所以最好用AssetDatabase.AssetPathToGUID获得资源的唯一id,然后存起来。获得了所有依赖关系之后,再使用BuildPipeline.PushAssetDependencies和BuildPipeline.PopAssetDependencies按照层级和顺序来打包。这样打出来的资源就完全的保留了依赖关系,文件也拆得很散很小,不会重复打包了。
在加载的时候,由于我们是预先记录了各个资源的依赖关系,所以在加载某一个资源的时候,先去保存的文件里面查找它的依赖关系,把所有用到的依赖资源都先加载一次,然后再加载它,就能完整的加载出一个想要的模型之类了。
这就是完整的旧版本AssetBundle依赖打包和加载的流程了。不过由于是受人指导学会的,所以不方便把全部代码贴出来。
再来看看5.0版本的心AssetBundle的使用情况:
看到新版本的AssetBundle,我那位同事估计会一口老血喷在屏幕上面。那是因为,这个辛辛苦苦做出来的打包策略,Unity已经集成了。
新版本的AssetBundle在打包的时候多了一个叫做BuildPipeline.BuildAssetBundles(outputPath)的方法,然后每一个资源可以设置一个assetBundleName。只要你调用这个方法,那么所有已经设置过assetBundleName的资源,就会自动打包,具体的好处有:
1、可以直接在编辑器UI上设置操作
2、提供了更简便的脚本API
3、Unity本身会处理所有的依赖关系
4、生成了一种叫做manifest的文件,用于记录资源之间的依赖关系,并以链式结构记录,修改时只需修改链的其中一环
5、增量打包功能。
以上的好处,是官方说明的,我大概操作了一下,说的都是事实,只是使用时有点需要注意的地方。
很明显的看出,这些优点,正是我那位同事已经做过的事情,和一些暂时没有做到的事情。
先来说说最多人关心的问题,Unity自己处理依赖关系。
实际上来说,所有需要打包成AssetBundle的资源,你是要先赋予它一个assetBundleName的,在它有了assetBundleName之后,实际上它的信息已经存在于AssetDataBase里面了。所以在打包的时候,只需要调用BuildPipeline.BuildAssetBundles方法,它会把记录了的在AssetDataBase里面的所有资源先计算出依赖关系,再拆分打包。这个步骤是一点问题都没有的。要注意的是,你所有依赖的资源都必须赋予assetBundleName,不然,依赖就不会被拆分。
在加载的时候,AssetBundle的特性是和旧版本一样的,就是当一个目标资源的依赖资源已经存在与内存中(也就是已经被加载过了),那么在加载目标资源的时候,Unity会自动的帮你找到依赖关系。所以在加载的时候实际上还是要你手动加载依赖资源的。这一点和旧版本一样。
再来说说打包工具的编写。
虽然官方说得很美好,一句BuildPipeline.BuildAssetBundles(outputPath)就可以直接把所有资源都打包了,而需要打包的资源可以在编辑器界面直接输入。但实际上由于上面说到的必须赋予每一个依赖资源assetBundleName,你不可能每一个资源去手动的查找用到的依赖资源再在编辑器输入名字,所以旧版本的打包流程还是要的。
首先,你可以遍历需要打包的文件夹,把所有需要打包的预设或者资源都找到,然后设置assetBundleName,然后,通过AssetDatabase.GetDependencies方法逐个找到资源的依赖资源路径,用AssetDatabase.AssetPathToGUID算出每个资源的唯一ID,然后将唯一ID当做assetBundleName赋予给每个依赖资源。最后,调用BuildPipeline.BuildAssetBundles(outputPath)打包到指定位置。
最后说说加载。
由于依赖关系都存在于manifest中,所以在加载资源之前,要先加载manifest文件。
实际上在打包的时候,会有一个总的manifest文件,叫做AssetBundle.manifest,然后每一个小的资源分别有一个自己的manifest文件。在我们加载的时候,需要
剩余内容已隐藏,支付完成后下载完整资料
资料编号:[150805],资料为PDF文档或Word文档,PDF文档可免费转换为Word
以上是毕业论文外文翻译,课题毕业论文、任务书、文献综述、开题报告、程序设计、图纸设计等资料可联系客服协助查找。