Unity5-ABSystem(二):AssetBundle导出

转载自:http://blog.csdn.net/lodypig/article/details/51871510

编辑器导出

设置AssetBundle

  在Project视图下选择一个资源或文件夹,即可在Inspector面板最下方找到Asset Label面板,点击菜单可以指定该资源所属的AssetBundle名称。 
AssetBundle creation 

  若要命名一个新的AssetBundle,可点击New创建一个,其他情况则可添加到已有的AssetBundle中。如果你创建了一个AssetBundle,却没有为它指定任何资源,可以使用”Remove Unused Names”,它将移除所有空的AssetBundle。 
AssetBundle creation 
  在Unity5中,AssetBundle的名称也可以代表相对路径,如图中environment/desert将创建名为desert的AssetBundle在environment目录下。但生成AssetBundle时并不会自动创建相应的目录,如果对应目录不存在,本次生成将失败。 
  


导出AssetBundle

  通过以上方式,我们可以设置资源导出成AssetBundle的对应关系,未设置的资源将不会包含在任何AssetBundle中。接着将以下代码添加到任意Editor目录下(如果没有可在任意地方创建一个)。

using UnityEditor;   

public class CreateAssetBundles
{
    [MenuItem ("Assets/Build AssetBundles")]     // 在Asset菜单下拓展Build AssetBundles按钮
    static void BuildAllAssetBundles ()          // 点击该按钮将执行本函数
    {
        BuildPipeline.BuildAssetBundles ("Path");   // 支持路径,如 Asset/AssetBundle/helloworld.ab
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

  编译之后,Asset菜单(编辑器上方或右键Project下资源弹出)即多出了Build AssetBundles,点击后将在Path对应路径导出AssetBundle。你可以使用”Path”也可以换成你喜欢的路径,路径起始于Assets目录,确保该路径存在。 
 我们使用了BuildPipeline.BuildAssetBundles接口来导出AssetBundle,这个接口的完全体如下。


BuildPipeline.BuildAssetBundles/3

    public static AssetBundleManifest BuildAssetBundles(string outputPath, 
      BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform);
 
 
  • 1
  • 2
  • 1
  • 2

  这里是三参的重载,下面会出现四参的重载。  
  参数含义如下:

 outputPath : 导出路径 
 BuildAssetBundleOptions  : 导出选项枚举 
 BuildTarget  : 导出平台枚举


BuildAssetBundleOptions

  None : 没有任何特殊要求。 
  UncompressedAssetBundle : 不压缩。 
  DisableWriteTypeTree : Assetbundle中不包含Type信息。TypeTree将在后面提到。 
  DeterministicAssetBundle : 使用资源的Hash ID来导出AssetBundle。使用ID可避免资源改名、移动位置等导致重新导出。 
  ForceRebuildAssetBundle : 强制重新导出。对已有的AssetBundle,在资源没有变化时,Unity不会重新导出。 
  IgnoreTypeTreeChanges : 增量打包时忽略Type信息变化。 
  AppendHashToAssetBundleName : 在AssetBundle名称后添加”_”加上Hash值。 
  ChunkBasedCompression : 使用块压缩,即LZ4压缩。


BuildTarget

  AssetBundle在不同平台下是不兼容的,对于不同平台的AssetBundle要分别进行导出。BuildTarget用来指定导出平台,例如BuildTarget.iOS。完整的枚举可以在Unity官方手册中找到。 
  通常可以使用EditorUserBuildSettings.activeBuildTarget,指定为Unity编辑器当前选择的平台。


Assetbundle变体(Variants)

AssetBundle variants  
  之前我们选择性忽略了AssetBundle右边还有一个菜单,这里可以用于指定AssetBundle变体。它有点像虚类的子类实现,用来解决例如在不同平台下使用不同资源的问题。上图中设置将导出myassets.hd,我们可以设置另一个变体为myasset.sd,确保两个AssetBundle中有相对应的资源,Unity将对两个AssetBundle中的资源使用同样的ID,使它们支持在运行时切换。 
  详细内容可以参考Unity官网手册


通过脚本设置AssetBundle

  在实际项目中,手动去为每个资源设置其AssetBundel及Variants会带来容易出错,影响心情,不易改动等副作用,所以最好通过脚本去设置。我们可以通过以下脚本设置资源AssetBundle及变体。

using UnityEditor;

public class SetAssetBundle {
    public void Example() {
        string path = "Assets/ReplaceMe.asset";
        AssetImporter ai = AssetImporter.GetAtPath(path);
        ai.assetBundleName = "AssetBundleName";
        ai.assetBundleVariant = "Variant";
    }
}


 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

脚本导出

示例

  除了在编辑器下设置AssetBundle名称外,我们还可以直接使用脚本导出,先感受一下。

using UnityEditor;
public class BuildAssetBundle
{
    static void Example()
    {
       /*
        *  1.创建building map实体
        *  2.指定Assetubndle名称
        *  3.(指定变体名称)
        *  4.指定资源路径
        *  5.导出
        */

        AssetBundleBuild abb = new AssetBundleBuild();   
        abb.assetBundleName = "myAssetBundle";             
        // abb.assetBundleVariant = "hd";
        abb.assetNames = new string[2] { "Assets/sprite/hello.png", "Assets/sprite/world.png" };
        BuildPipeline.BuildAssetBundles("Assets/AssetBundle", new AssetBundleBuild[1] { abb });
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

  这段代码将”Assets/sprite/hello.png”和”Assets/sprite/world.png”导出到Assets/AssetBundle/myAssetBundle中。建议自己在Unity中尝试一下,加深印象,后面我们将默认采用这种方式。


AssetBundleBuild结构体

  上面导出过程中,我们首先创建了AssetBundleBuild结构体,这个结构体长下面这样:

namespace UnityEditor
{
    //  AssetBundle building map 实体.
    public struct AssetBundleBuild       
    {
        public string assetBundleName;         // AssetBundle 名称.
        public string assetBundleVariant;      // AssetBundle 变体.     
        public string[] assetNames;            // 该AssetBundle包含的资源路径列表。
    }
}
 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

BuildPipeline.BuildAssetBundles/4

  相较于3参的,这里多出了一个AssetBundleBuild[] builds,对应上面创建的AssetBundleBuild对象,一个AsssetBundleBuild最终会导出一个AssetBundle,而列表代表我们可以一次导出多个AssetBundle。

    public static AssetBundleManifest BuildAssetBundles(string outputPath, AssetBundleBuild[] builds, 
      BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform);
 
 
  • 1
  • 2
  • 1
  • 2

Mainfest

  如果有运行上面代码,就会发现每导出一个AssetBundle文件,就会附带生成一个同名的.manifest文件。除此之外,在outputPath目录下,还自动生成了与目录同名的AssetBundle及.manifest文件。Manifest只是一个文本文件,可以用任何文本编辑器打开,他提供了诸如CRC和资源依赖的信息。一个Mainfest可能会长这样:

ManifestFileVersion: 0 
CRC: 2422268106 
Hashes: 
 AssetFileHash:   
   serializedVersion: 2 
   Hash: 8b6db55a2344f068cf8a9be0a662ba15 
 TypeTreeHash: 
   serializedVersion: 2 
   Hash: 37ad974993dbaa77485dd2a0c38f347a 
HashAppended: 0 
ClassTypes: 
- Class: 91  
 Script: {instanceID: 0} 
Assets: 
 Asset_0: Assets/Mecanim/StateMachine.controller 
Dependencies: {}

  至于与目录同名的.manifet文件,提供了所有AssetBundle之间依赖关系,我们可以叫它总manifest文件。而那个不请自来的AssetBundle中包含的就是总manifeset文件。 
  一份存在依赖关系的总manifest可能长下面这样。

ManifestFileVersion: 0 
AssetBundleManifest: 
AssetBundleInfos: 
Info_0: 
Name: image.ab 
Dependencies: {} 
Info_1: 
Name: none.ab 
Dependencies: {} 
Info_2: 
Name: sprite1.ab 
Dependencies: 
Dependency_0: common.ab 
Info_3: 
Name: sprite123.ab 
Dependencies: 
Dependency_0: common.ab 
Info_4: 
Name: sprite1234.ab 
Dependencies: 
Dependency_0: common.ab 
Info_5: 
Name: sprite2.ab 
Dependencies: 
Dependency_0: common.ab 
Info_6: 
Name: sprite234.ab 
Dependencies: 
Dependency_0: common.ab 
Info_7: 
Name: sprite3.ab 
Dependencies: 
Dependency_0: common.ab 
Info_8: 
Name: sprite4.ab 
Dependencies: 
Dependency_0: common.ab 
Info_9: 
Name: common.ab 
Dependencies: {}


TypeTree

  Manifeset里面还有一些如Class ID的字样,指的是AssetBundle的TypeTree。关于TypeTree的资料非常少,可以知道它记录了一个Class ID,Class ID对应的Class可以在这里找到,Unity利用Class ID来序列化或反序列化一个类,这份信息也可以包含在引擎里,所以AssetBundle导出时有一个选项可以不导出这部分,可以轻微减少包大小和提高加载速度。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值