Unity5.4 Assetbundles官方说明一(AssetBundles打包详解)
转载请注明出处!
目前网上有一些关于Unity5的Assetbundles不错的中文教程,例如:
1、http://liweizhaolili.blog.163.com/blog/static/16230744201541410275298/阿赵
http://liweizhaolili.blog.163.com/blog/static/162307442015282017852/阿赵
2、http://www.it165.net/pro/html/201506/43896.html
当时刚学Unity5的Assetbundles的时候,学了好久头绪还是有点乱,后来直接看官方文档的教程,勉强基本掌握了Unity5的Assetbundles的使用。下面就把我在官方文档学到的关于Assetbundles的内容分享给大家,希望对大家有帮助(我用的是Unity5.3版本)。AssetBundle资源包是什么文件,我将不再进行解释,网上也有好多资料的,我将按照官方文档的教程进行详解,希望大家多多指点。PS:本人英语不太好,翻译的不太准确的话,望大家指正并谅解。最后祝大家学习愉快。
首先特别说明一下:资源包就是指AssetBundle,我们打包后的文件主要就是资源包,而资源是包含在资源包中,也是我们常用的模型、材质、纹理贴图等等资源,接下来的文章中希望大家能分清“资源”和“资源包”这两个名词。
一、打包Assetbundles资源
开始创建一个AssetBundle,从项目文件夹中选择一个想要打包的资源对象,在Inspector检查器窗口的底部是AssetBundle菜单,从第一个下拉框中选择或设置AssetBundles的名称,第二个下拉框是附加选项,来定义一个变体包,将在下面详解(注意:如果资源是第一次打包,请不要设置第二个附加选项,否则打包报错)。默认情况下,AssetBundle名称设置为None,这意味着资源不能进行AssetBundle打包。如果你还没有定义了一个包,单击New…,输入一个包名。这样就可以创建一个或多个AssetBundles,打包的名字就是设置的名字。

AssetBundle名称可以使用“/”符号进行分级,便于管理。在下面的例子中,资源已经被添加到了一个称“environment/desert”的AssetBundle。而这个“environment/desert”的AssetBundle可能包含多个资源,即有多个资源选择了同一个Assetbundle(注意:AssetBundle名字总是小写,如果你使用大写字符的名称,他们被转换为小写)。如果创建的AssetBundles没有分配给资源,即存在没有使用的AssetBundle名称,可以使用“ Remove Unused Names”选项删除未使用的名称。

下面是脚本执行打包Assetbundle资源的代码:
/// <summary> /// 自动打包资源(设置了Assetbundle Name的资源) /// </summary> [MenuItem("AssetBundle/Build AssetBundles 01")] //设置编辑器菜单选项 static void BuildAllAssetBundles() { //打包资源的路径 string targetPath = Application.dataPath + "/StreamingAssets"; //打包资源 BuildPipeline.BuildAssetBundles(targetPath, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows); //刷新编辑器 AssetDatabase.Refresh(); }
在编辑器找到设置的菜单选项,然后点击这个菜单选项后会调用设置的打包函数,Unity引擎会自动进行打包,即将设置了AssetBundle名称的所有资源和预设,全部打包(注意:需要先手动创建一个要打包资源的路径,否则不能打包。例如:这里我先在项目里创建了StreamingAssets文件夹)。

然后会在打包的资源路径下找到打包的资源,每个打包的资源名称就是在Unity中选择的Assetbundle名称。此外,每个AssetBundle都有一个扩展名为“.manifest”的关联文件,这是一个文本文件,可以用任何文本编辑器打开查看,它记录了资源的CRC、打包资源的路径、资源之间的依赖关系等信息,并以链式结构记录,修改时只需修改链的其中一环。AssetBundle在上面的官方示例中有一个这样的文件:

二、Shader的分离打包操作
当在打包的资源中包含Shader文件时,Unity会根据当前场景和lightmapping的设置来决定使用哪个Lightmap(光照贴图)模式。这意味着在打包时,需要一个配置好的场景并且是打开的场景。
当然也可以手动指定从哪一个场景中计算Lightmap(光照贴图)的模式。打开想使用的场景,在图形设置Inspector监视器窗口(Edit > Project Settings > Graphics),找到Shader stripping,设置Lightmap modes为Manual,,然后点击From current scene按钮,中间几个单选框会被自动打勾或勾掉。如下图所示(官方):

三、AssetBundle编辑工具
1、获取AssetBundle的名称
下面的脚本是显示所有将会被打包的AssetBundle资源名称,并在后台输出。
/// <summary> /// 查看所有的Assetbundle名称(设置Assetbundle Name的对象) /// </summary> [MenuItem("AssetBundle/Get AssetBundle names")] static void GetNames() { var names = AssetDatabase.GetAllAssetBundleNames(); //获取所有设置的AssetBundle foreach (var name in names) Debug.Log("AssetBundle: " + name); }
2、当AssetBundle资源名称发生变化时,会得到通知。(这个脚本无需挂到物体上,会自动检测运行,当改变资源AssetBundle的名称时,会在后台打印出相关信息)
using UnityEngine; using UnityEditor; public class MyPostprocessor : AssetPostprocessor { //使用AssetPostprocessor类定义的函数OnPostprocessAssetbundleNameChanged回调 //当AssetBundle的名称发生变化时,编辑器会自动执行以下函数,返回变化信息 public void OnPostprocessAssetbundleNameChanged(string assetPath, string previousAssetBundleName, string newAssetBundleName) { Debug.Log("Asset " + assetPath + " has been moved from assetBundle " + previousAssetBundleName + " to assetBundle " + newAssetBundleName); } }
四、AssetBundle的变体
这可用于实现类似AssetBundle资源的相同结果。例如,可以设置AssetBundle的变体为“myassets.hd”和“myassets.sd”。在此,Unity为了确保资源完全匹配,打包时BuildPipeline类为这个带有两个变体AssetBundle的资源对象提供了相同的内部ID,现在这两个变种AssetBundles可以任意切换,用AssetBundles的不同变体可以在在运行时扩展(再次说明:如果资源是第一次打包,请不要设置第二个附加选项,否则打包报错)。设置如下图:

(注意:完整的AssetBundle名字是AssetBundle名字和变体名字的结合。例如:如果添加了一个名为“myassets.hd”的变体AssetBundle,应该设置AssetBundle的名字为“myassets”,变体的名字为“hd”)
五、用API的脚本把资源设置为AssetBundle 官方API给出了一个AssetImporter类(作为特殊资源类型派生的资源导入器的基类),来用脚本对AssetBundle的设置进行一些操作,再次只列举几个用法,用脚本设置AssetBundle的名称和变体名,代码如下://注意此处的basePath是Assets开头的路径:Assets/...
AssetImporter importer = AssetImporter.GetAtPath(basePath); //获取要设置的资源导入器
importer.assetBundleName = assetName; //设置AssetBundle名称
importer.assetBundleVarian = assetVarian; //设置AssetBundle变体名
注意:AssetImporter是一个编辑器类,如果想使用它你需要把它放到工程目录下的Assets/Editor文件夹下。编辑器类在UnityEditor命名空间下。所以当使用C#脚本时,你需要在脚本前面加上 “using UnityEditor”引用。六、BuildPipeline.BuildAssetBundles()打包方法的基本参数说明 AssetBundleManifest BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions = BuildAssetBundleOptions.None, BuildTarget targetPlatform = BuildTarget.WebPlayer);
outputPath:输出路径 assetBundleOptions:打包参数设置,默认是BuildAssetBundleOptions.None(下方有详解) targetPlatform:打包的目标平台,默认为BuildTarget.WebPlayer 还有一个重载方法里多了一个参数AssetBundleBuild[] builds,这个参数包含了从资源到AssetBundle的映射关系,例如设置AssetBundle名称与Asset名称的映射关系。这提供了一定的灵活性:我们可以通过脚本设置映射信息并在打包时构建映射关系,当然这个映射信息不能替代或更改现有的资源库。个人感觉这个扩展方法不常用,以下是官方提供的例子:
using UnityEngine;
using UnityEditor;
public class BuildAssetBundlesBuildMapExample : MonoBehaviour
{
[MenuItem( "Example/Build Asset Bundles Using BuildMap" )]
static void BuildMapABs( )
{
// Create the array of bundle build details.
AssetBundleBuild[] buildMap = new AssetBundleBuild[2];
buildMap[0].assetBundleName = "enemybundle";
string[] enemyAssets = new string[2];
enemyAssets[0] = "Assets/Textures/char_enemy_alienShip.jpg";
enemyAssets[1] = "Assets/Textures/char_enemy_alienShip-damaged.jpg";
buildMap[0].assetNames = enemyAssets;
buildMap[1].assetBundleName = "herobundle";
string[] heroAssets = new string[1];
heroAssets[0] = "char_hero_beanMan";
buildMap[1].assetNames = heroAssets;
BuildPipeline.BuildAssetBundles( "Assets/ABs", buildMap, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows );
}
}
七、在AssetDatabase资源库中操作AssetBundle的相关API
- string[] GetAllAssetBundleNames():返回资源库中所有的AssetBundle名称(即我们设置过的名称)
- string[] GetAssetPathsFromAssetBundle(string assetBundleName):返回Assetbundle名称为assetBundleName的所有资源路径
- bool RemoveAssetBundleName(string assetBundleName, bool forceRemove):从AssetBundle资源库中删除assetBundleName名称,forceRemove为true表示就算有资源使用这个名称也会删除,forceRemove为false表示只删除未使用的AssetBundle名称
- string[] GetUnusedAssetBundleNames():返回所有未使用的AssetBundle名称
- void RemoveUnusedAssetBundleNames():删除所有未使用的AssetBundle名称
-
七、关于BuildAssetBundleOptions打包参数说明
-
- CollectDependencies:包含所有依赖项(Unity5.x中已过时,被新的打包系统替代,可忽略此项);
- DeterministicAssetBundle:使每个Object具有唯一的、不变的HashID(Unity5.x中已过时,被新的打包系统替代,因为打包的资源都会创建一个ID,可忽略此项);
- UncompressedAssetBundle:在创建AssetBundle包时不压缩的方式打包;
- DisableWriteTypeTree:在AsserBundle包中不包含类型信息;
- ForceRebuildAssetBundle:强制重新打包AssetBundle;新增
- IgnoreTypeTreeChanges:用于判断AssetBundle更新时,是否忽略TypeTree的变化。表示当打包的资源没有变化,但是类型树却发生了改变,那么将不会重新打包AssetBundle,与DisableWriteTypeTree冲突。新增;
- AppendHashToAssetBundleName:这个选项将会在打包的时,将打包出来的资源名称后面自动添加上哈希id;
- ChunkBasedCompression:这个选项表示在打包AssetBundle时使用LZ4进行压缩。当从AssetBundle读取数据时可以实时解压。5.3版本新增。
-
-
八、Manifest文件说明
- ManifestFileVersion:文件的版本信息
- CRC
- Hashes:哈希信息,包含两种
- (AssetFileHash:资源文件的哈希信息,表示了包含在这个AssetBundle中的所有资源的哈希信息,仅用于重建;
- TypeTreeHash:类型树的哈希信息,表示了包含在这个AssetBundle中的所有类型的哈希信息,仅用于重建。)
- ClassTypes:类的类型值,包含在这个AssetBundle中所有的类的类型值,当进行类型树的增量重建时,这些会用来获取新的哈希值
- Assets:资源路径名称,包含在这个AssetBundle中的所有资源的路径名
- Dependencies:依赖的所有Assetbundle的路径名称
- 同时每一个AssetBundle文件都会带有一个Manifest文件,这个文件中包含类型哈希值、资源的路径星系、依赖项的打包信息等。
-
- 九、AssetBundle加载的API说明
- string[] GetAllAssetNames():返回所有AssetBundle的普通资源名,非流形式场景资源。
- string[] GetAllScenePaths():返回AssetBundle中所有场景资源的路径,只适用于流形式的场景。
- Object LoadAsset(string name):加载资源对象,还有另外两个重载:Object LoadAsset(string name, Type type)和T LoadAsset(string name)。
- Object[] LoadAllAssets():加载Assetbundle中包含的所有资源对象,另一个重载是Object[] LoadAllAssets(Type type)。
- 上一篇:没有了
- 下一篇: Unity3d中对象池(ObjectPool)的实现