Unity资源管理——AssetBundle构建/打包

1、为资源设置 assetBundleName 和 assetBundleVariant。

    可以在资源的 Inspector 上手动设置,也可以通过 AssetImporter 进行设置。

AssetImporter importer = AssetImporter.GetAtPath(assetPath);
importer.assetBundleName = abName;
importer.assetBundleVariant = abVariant;

    实际项目中,通常需要提前制定好 AssetBundle的分组策略,然后规划好 “哪些目录要做怎样的打包处理”,这样才能够批量地对项目中所有的资源设置 assetBundleName 和 assetBundleVariant。

比如:

     1、某目录下的所有资源(递归至底)捆打为1个包。

     2、某目录下的所有资源(递归至底)各自打为1个包。

     3、某目录的下一级目录中的所有资源(递归至底)各自打为1个包。

     ......

2、唯一打包 API,BuildPipeline.BuildAssetBundles()

    在Unity2019.2中,它有两个重载(其他API已废弃)如下:

//Build all AssetBundles specified in the editor.
//构建所有编辑器中指定了AssetBundleName的资源。(通过前期设置)
public static AssetBundleManifest BuildAssetBundles(string outputPath, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform);

//Build AssetBundles from a building map.
//构建资源,通过传入的构建列表。(通过纯代码配置)
public static AssetBundleManifest BuildAssetBundles(string outputPath, AssetBundleBuild[] builds, BuildAssetBundleOptions assetBundleOptions, BuildTarget targetPlatform);

      注意:这个API在打包时,本身就是增量的(如果某个资源没有发生变化,就不会重新对该资源打包),不用自己去做增量逻辑。为什么要增量打包?因为增量打包可以大幅节省总的构建时间。

      Unity 根据 已生成的、与 “XXX资源” 一一对应的 “XXX.manifest” 文件中的记录来判断资源是否发生了变化。

      依据:除非删除了 “XXX.manifest”,Unity才会对 “XXX资源” 重新打包。否则就算删除了 “XXX” 的bundle文件也不会重新打包。

      如果想要强制重新打包,可以在打包参数中添加 BuildAssetBundleOptions.ForceRebuildAssetBundle。

3、可选的打包参数 BuildAssetBundleOptions。

public enum BuildAssetBundleOptions
{
    //Build assetBundle without any special option.
    //不指定任何选项进行打包。
    //默认使用 LZMA 格式压缩。
    //LZMA 压缩率较大、压缩产物较小,但加载前需要完整解压,所以加载时间相对较长。
    //加载时,Unity 会先将 LZMA 格式的包解压,再使用 LZ4 格式重新压缩(会占用内存),最后再使用。
    //使用 LZMA 格式,意味着要使用包中的一个资源就得解压整个包。
    //用例:单个或强关联的一组资源。如,打包角色或场景的所有资源。
    None = 0,

    //Don't compress the data when creating the asset bundle.
    //打包时不进行数据压缩。
    //这使得打包和加载更快!但由于它更大,下载就需要更长的时间。
    //需要根据实际需求进行权衡。
    UncompressedAssetBundle = 1,

    //Includes all dependencies.
    //包含所有依赖。
    CollectDependencies = 2,
    
    //Forces inclusion of the entire asset.
    //强制包含整个asset。
    CompleteAssets = 4,
    
    //Do not include type information within the AssetBundle.
    //不在打包时写入TypeTree信息。
    //默认高版本的Unity可使用低版本Unity打包的AssetBundle。
    //如果开启此选项,AssetBundle会更小(优点),但也破坏了这种向下兼容性(缺点)。
    //NRatel建议:不要开启此选项,除非你能保证你的游戏绝不会在开发和运营过程中不更新Unity版本。
    DisableWriteTypeTree = 8,
    
    //Builds an asset bundle using a hash for the id of the object stored in the asset bundle.
    //使用存储在AssetBundle中的对象id的hash值来打包。用于增量更新,可以避免文件重命名、位置改动等操作导致的重新打包
    //注意: 此功能总是启用的。*(疑问?那如何关闭?)
    DeterministicAssetBundle = 16,
    
    //Force rebuild the assetBundles.
    //强制重新打包,即使原始资源没有任何改变。(反增量打包)
    ForceRebuildAssetBundle = 32,
    
    //Ignore the type tree changes when doing the incremental build check.
    //在执行增量打包检查时忽略 typeTree 的更改。
    //即:如果包含的asset没有改变,但是类型树改变了,那么目标AssetBundle不会被重新打包。
    IgnoreTypeTreeChanges = 64,
    
    //Append the hash to the assetBundle name.
    //将hash值附加到assetbundle名字上。可以用来解决cdn文件缓存问题
    AppendHashToAssetBundleName = 128,
    
    //Use chunk-based LZ4 compression when creating the AssetBundle.
    //在打包时使用基于块的 LZ4 压缩方式。
    // LZ4 压缩率较低、压缩产物较大,加载前不需要解压整个包,而是在某个资源加载时实时解压缩该资源所在的块,所以加载时间相对较短。
    ChunkBasedCompression = 256,
    
    //Do not allow the build to succeed if any errors are reporting during it.
    //如果在打包过程中报告了任何错误,都不允许打包成功。
    //如果没有这个标志,非致命的错误—例如为特定平台编译着色器失败—将不会导致构建失败,但是可能会在运行时导致不正确的行为。
    //NRatel认为:应该总是开启此选项,将所有可能出现的问题都暴露在开发阶段。
    StrictMode = 512,
    
    //Do a dry run build.
    //执行预演打包。
    //这不会对asset进行真实的打包,仅会返回有效的、包含依赖关系的AssetBundleManifest文件。
    DryRunBuild = 1024,
    
    //Disables Asset Bundle LoadAsset by file name.
    //禁用按 “asset文件名” 加载asset的方式。
    //加载AssetBundle中的asset,默认有三种方式:“完整的asset路径”、“asset文件名” 和 “带有扩展名的asset文件名”。
    //此选项目的:节省运行时内存和加载性能。
    DisableLoadAssetByFileName = 4096,

    //Disables Asset Bundle LoadAsset by file name with extension.
    //禁用按 “带有扩展名的asset文件名” 加载asset的方式。
    //加载AssetBundle中的asset,默认有三种方式:“完整的asset路径”、“asset文件名” 和 “带有扩展名的asset文件名”。
    //此选项目的:节省运行时内存和加载性能。
    DisableLoadAssetByFileNameWithExtension = 8192
}

4、压缩 疑问/策略?

疑问:Unity 会自动解压 LZMA格式的 AssetBundle 并重新压缩为LZ4格式。这发生在什么时候?

1、若 Caching.CompressionEnabled 为 true,LZMA 格式的 AB 将在下载时解压并使用LZ4进行缓存。

2、使用 AssetBundle.LoadFromFile 加载 LZMA 格式的 AB 时,AB将在内存中被解压。

策略:

    1、打包时使用LZ4格式,不再做其他任何处理。

    2、打包时使用LZ4格式,然后用自定义的压缩格式进一步压缩。

    3、打包时使用非压缩格式,然后用自定义的压缩格式压缩。

5、打包产物:

(1)、目标 AssetBundle,分两种。

    普通 AssetBundle 的结构(较松散):

Unity资源管理——AssetBundle构建/打包_第1张图片

    场景 AssetBundle 的结构(它针对场景及其内容的串流加载进行了优化):

Unity资源管理——AssetBundle构建/打包_第2张图片

------------------------------------------------ NRatel 割 ------------------------------------------------

    如果你好奇AssetBundle内部结构到底是怎样的。可以利用 WebExtract.exe 和 binary2text.exe(windows的话,都在Unity安装目录的 \Editor\Data\Tools\ 下),将 AssetBundle 解开。用法如下(在命令行下操作):

#assetbundle => binaryfile
#Scene的AB解开为 BuildPlayer- 和 BuildPlayer-.sharedAssets。
#普通的AB解开为一个 CAB- 的档。
#BuildPlayer- 和 CAB- 对应的就是 Profiler 里面 Others/SerializedFile 里面的名字。
#还有一些后缀为 .resS 的文件,应该就是实际的资源吧。
WebExtract.exe inputassetbundle    

#binaryfile => textfile
binary2text.exe inputbinaryfile [outputtextfile] [-detailed] [-largebinaryhashonly] [-hexfloat]  

Unity资源管理——AssetBundle构建/打包_第3张图片

(2)、与目标 AssetBundle 对应的 文本格式的清单文件。

    名称与 目标 AssetBundle 相同,后缀为 “.manifest” 。

    它的作用有俩:1、肉眼观看 AssetBundle 包含的资源、依赖项和其他信息;2、被Unity用来做增量打包。

(3)、总的清单 AssetBundle。

     一个额外生成的、名为 “AssetBundles输出根路径” 的、无后缀的、只包含了一个固定名为 “AssetBundleManifest” 的 Asset的  AssetBundle 文件。

     记载了所有 AssetBundle 及其依赖关系。加载AssetBundle时,如果需要提前加载其依赖项时使用。

(4)、与总的清单 AssetBundle 对应的、文本格式的清单文件。

     记载了所有 AssetBundle 及其依赖关系。肉眼观看用。

你可能感兴趣的:(Unity游戏开发,Unity资源管理,AssetBundle,Unity,热更新,Unity)