Hugo Future Imperfect Slim

L-Lawliet's Blog

记录游戏开发的点点滴滴

YooAsset插件

学习YooAsset插件和分析

Lawliet

1 分钟

Colourful

YooAsset是一个Unity资源系统,集合资源打包、分包、更新、加载等。

信息

  • 官网:YooAsset
  • 版本:1.4.2
  • 源码:https://github.com/tuyoogame/YooAsset

构建

收集

  1. 检测配置合法性
  2. 收集所有Package的资源(遍历所有的Group,然后再遍历所有的Collector)
AssetBundleCollectorSettingData.Setting.GetPackageAssets(buildMode, packageName);
  1. 剔除未被引用的依赖资源
  2. 录入所有收集器收集的资源
  3. 录入相关依赖的资源
  4. 记录关键信息
  5. 填充主动收集资源的依赖列表
  6. 计算完整的资源包名
  7. 移除不参与构建的资源
  8. 构建资源包

Runtime

初始化

  • YooAssets初始化。
    • 创建驱动器YooAssetsDriver用于调度系统的Update
    • 创建远程调试器RemoteDebuggerInRuntime用于调试加载情况
    • 初始化异步系统OperationSystem
// 初始化资源系统
YooAssets.Initialize();
  • 创建Package。
    • 创建package
    • 设置为默认的package
// 创建默认的资源包
var package = YooAssets.CreateAssetsPackage("DefaultPackage");

// 设置该资源包为默认的资源包,可以使用YooAssets相关加载接口加载该资源包内容。
YooAssets.SetDefaultAssetsPackage(package);
  • 初始化资源系统(Editor模拟)
    • EditorSimulateModeHelper.SimulateBuild会调用AssetBundleSimulateBuilder构建资源清单
    • 再把Parameters传入package进行资源清单初始化
    • package根据mode创建EditorSimulateModeImpl,这是包含了IPlayModeServicesIBundleServices具体实现的集合。
    • package创建AssetSystemImpl,然后进行初始化。
    • EditorSimulateModeImpl进行初始化。
    • 调用EditorSimulateModeInitializationOperation加载清单,并且设置清单到EditorSimulateModeImpl
var createParameters = new EditorSimulateModeParameters();
createParameters.SimulatePatchManifestPath = EditorSimulateModeHelper.SimulateBuild(packageName);
InitializationOperation initializationOperation = package.InitializeAsync(createParameters);
  • 初始化资源系统(单机模式)
    • Parameters传入package进行资源清单初始化
    • package根据mode创建OfflinePlayModeImpl,这是包含了IPlayModeServicesIBundleServices具体实现的集合。
    • package创建AssetSystemImpl,然后进行初始化。
    • OfflinePlayModeImpl进行初始化。
    • 调用OfflinePlayModeInitializationOperation
      • 获取Package版本号
      • 加载清单。
      • 设置清单到OfflinePlayModeImpl
      • 校验清单的资源包,将正确的补丁放入CacheSystem
var createParameters = new OfflinePlayModeParameters();

InitializationOperation initializationOperation = package.InitializeAsync(createParameters);
  • 初始化资源系统(联机模式)
    • Parameters传入package进行资源清单初始化
    • package根据mode创建HostPlayModeImpl,这是包含了IPlayModeServicesIBundleServices具体实现的集合。
    • package创建AssetSystemImpl,然后进行初始化。
    • HostPlayModeImpl进行初始化。
    • 调用HostPlayModeInitializationOperation
      • 获取补丁水印(安装包版本号和补丁版本号),如果水印不一致,则清空缓存目录。
      • 获取缓存目录Package版本号,如果存在,则加载和解析缓存目录清单
      • 在缓存目录清单加载失败(版本号不对、hash值不对、清单不存在等),则获取安装包Package版本号,并且把版本号和清单写入到缓存目录。最后再加载安卓包清单。
      • 设置清单到HostPlayModeImpl
      • 校验清单的资源包,将正确的补丁放入CacheSystem
var createParameters = new OfflinePlayModeParameters();

InitializationOperation initializationOperation = package.InitializeAsync(createParameters);

更新

//更新Package版本信息
var operation = package.UpdatePackageVersionAsync();

yield return operation;

//更新Package资源清单
package.UpdatePackageManifestAsync(operation.PackageVersion);

//创建下载器
var downloader = YooAssets.CreatePatchDownloader(downloadingMaxNum, failedTryAgain);

只有联机模式才有更新系统

  • HostPlayModeUpdatePackageVersionOperation请求远端版本号信息。
  • HostPlayModeUpdatePackageManifestOperation更新补丁清单。
    • 加载Cache清单,判断版本号是否为最新
    • 当版本号不是最新时,下载远端清单到Cache目录。
    • 重新加载Cache清单。
    • 校验清单的资源包,将正确的补丁放入CacheSystem
  • PatchDownloaderOperation下载补丁(不包含已有缓存、内置资源)
  • 清除过期的补丁文件

扩展

由于代码比较简单易懂,并且框架解耦的较好,扩展性比较好。

更新

目前热更方式为CDN获取版本信息,可以增加后台模式,以适应后台更新的方案。

//AssetsPackage.InitializeAsync()

if (...)
{
  ...
}
else if (_playMode == EPlayMode.ServerPlayMode)
{
  var serverPlayModeImpl = new ServerPlayModeImpl();

  ...
}

疑问

  • 覆盖安装情况下,资源是否正常?

会通过水印判断安装包是否有变更,如果安装包变更了,则清除Cache目录

  • 断点续传是否会出现缺漏的问题?

每次会对文件计算hash值进行校验。没有缺漏问题。

  • 热更是否要在Cache增加一份副本?

安装包的内容只有一份。热更时会使用IsBuildinPatchBundle进行判断剔除。

  • CDN需要全量补丁?

发布没有差异补丁的概念,所以都是全量补丁

对比

Addressable

  • Group与Addressable的差不多,都是用于资源分组使用
  • 没有了自定义Entry的概念,取而代之增加了Collector对资源进行收集设置。
  • 收集器的地址保存的是字符串,移动文件夹时会出现丢失的问题。
  • 获取Entry地址和寻址信息需要手动拼写
  • Tags只能对Group设置,无法只对Collector和Entry设置
  • Group相对于Addressable去除了很多独立设置,无法对AB进行独立设置压缩方式,命名方式等
  • 地址和寻址两套方式可以选择使用
  • 支持旧的构建模式和SBP模式
  • 配置有Json和Bytes两种,bytes只是简单序列化了,并没有做压缩处理。
  • Group之上还增加了Package的概念,用于构建时可以分情况构建。
  • 有多种构建模式,例如演练和模拟模式可以方便调试
  • 有调试器和报告查看工具
  • 更新地址需要运行设置。
  • 支持构建原文件
  • Editor模拟模式,需要每次运行时调用构建,需要生成列表清单。目前只有收集到的资源需要生成清单,理论上速度应该不慢。
  • 构建时才会检查资源是否重复收集
  • Operation采用的是Update来处理,没有采用协程。Operation通过状态来去区分任务,需要等待子Operation完成来改变状态。
  • 有加密接口。Android采用加密只能使用偏移头文件的方式,如果采用其他方式,将无法加载SteamingAsset目录资源。

问题

  • 缺少SpriteAtlas打包
  • 加载场景时,会自动清空资源引用计数,导致对象池中的对象丢失资源引用。

优点

  • 代码结构较为简单,容易扩展
  • 多线程下载
  • 多线程校验文件
  • 开箱即用

缺点

  • 每次都需要校验文件,全量计算文件Hash,数量一多会比较耗时
  • 收集器需要填写配置,有资源需要特殊处理时,比较难处理
  • 补丁为全量资源上传CDN,如果改成增量补丁,并且按版本分开目录,需要扩展新的mode。
  • 寻址的Key值无法自定义,相同文件名会出现Key重复的问题。

说些什么

评论

还沒有留言。

最新文章

Colourful

HLSL

分类

关于

记录游戏开发的点点滴滴