转载请注明出处!
目前网上有一些关于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资源的代码:
/// <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文件夹)。
二、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”)
//注意此处的basePath是Assets开头的路径:Assets/...
AssetImp
orter imp orter = AssetImp orter.GetAtPath(basePath); //获取要设置的资源导入器
importer.assetBundleName = assetName; //设置AssetBundle名称 imp
orter.assetBundleVarian = assetVarian; //设置AssetBundle变体名
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 );
}
}
- 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文件,这个文件的名字跟打包的主路径文件夹名称一致,这个总的Manifest只用于增量重建,不是程序运行时必需的。 -
同时每一个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 )。