AssetBundle系统之(一)打包

系统所做的事情:
1.打包(分析依赖,增量打包)
2.加载(依赖关系加载,多版本支持)
3.卸载(自动卸载无引用资源)


1.先说一下打包规则
为了打包方便,需要定制一套打包规则。
这里的规则:
a.基于文件夹的策略打包
b.打包规则分为 SelfName(资源自身名字为包名)
c.打包规则分为 ForderName(资源所在文件夹为包名)

具体策略:

如图所示:
预制体放在一个文件夹,采用SelfName。
精灵图片放在一个文件夹,采用SelfName。
声音放在一个文件夹,采用FolderName。
(仅仅只是演示,具体策略需要根据项目不同的需求来制定)
(把登陆之前打成一个group,登陆后释放;把每个活动打成一个group等等)

那么上图是什么呢?
就是一个打包编辑器,可以配置需要导出的资源。
本质上就是一个ScriptableObject,通过扩展编辑器开发个UI界面。

定义一个AssetBundleConfig:

创建一个

AssetBundleConfig config= ScriptableObject.CreateInstance<AssetBundleConfig> ();
AssetDatabase.CreateAsset (config, path);

创建后如图所示:


规则定完后,开始打包。
2.打包逻辑
打包逻辑主要分五步:
**a.Begin:**准备阶段,负责读取上一次保存的缓存文件。

上图为缓存文件,第一行是版本号。
然后是资源路径,资源文件Hash值,资源所在包Hash值,依赖数量,如果有的话,下面还有包的hash值。
Hash的用处:
1.文件Hash:判断这个资源是否需要增量打包,通过读取文件的byte[]数组获取。
2.包Hash:判断这个包是否需要热更,通过打包后的AssetBundleManifest文件获取。

**b.LoadAssetTargets:**加载所有的资源,构造AssetTarget对象
为什么要加载资源?
分析依赖
为什么5.x还要分析,不是4.x的时候才要分析吗?
1.为了构建自己的name-assetPath数据表,在编辑器下无需打包就能加载资源。
2.分析是否包含冗余资源。
假如说:美术偷偷传了一个材质的文件夹,他不会配到打包配置里面,就有很多prefab是依赖这个资源的。所以很多包都会包含这个资源,就会造成资源的冗余。如果事先分析,发现这种情况,就可以把这个资源,单独导出包,让其他的资源依赖这个包就可以了。
并且只需要设置一个包名,因为5.x已经帮我们做了依赖管理:如果引用的资源是单独的包,那就添加一个依赖项;如果不是,那就把这个资源包含在自己的包内。
那打包的时候设置一下这个材质不就行了吗?
这只是一种容错的方法,有些情况是不可预想的。好的团队按照规则固然重要,但是写工具要从底层处理问题,而不是依赖认为的策略去解决问题。
AssetTarget 对象是啥?

如上图,记录了:
文件信息,对应的资源,以及资源的路径、被设置的包名、当前的资源名,
以及导出规则、hash值、缓存信息、我依赖的资源、以及依赖我的资源。

作用:针对单个资源管理
1.包名与资源路径,在最后Build的时候,需要构建AssetBundleBuild
2.asset为什么要加载进来?通过EditorUtility.CollectDependencies(asset)做依赖查询
(但不是必须的,因为各种组件都会被列出来。可以无需加载asset,直接通过 AssetDatabase.GetDependencies(path),同样会获取到依赖信息,且是Gameobjec级别的。)
3.AssetCacheInfo就是文件Build之后的,缓存信息,下一次增量时会根据此比较。
4.依赖我的集合,用来做冗余剔除,如果数量超过1,就需要单独导出包。
5.ExportRule导出规则,就是之前的SelfName、FolderName,为什么还会No呢?
如果这个资源没有设置过需要导出,且只有一个包依赖次资源,Unity会把这个资源打入到这个包内,而无需导出。

**c.Analyze:**分析依赖,剔除冗余
1.开始分析,首先要获取上次的Build后的缓存信息。
如果有,并且本次资源的Hash值和之前缓存的Hash值不一样,那就需要重新导出。
如果没有,或者是Hash值一样,那就不需要重新导出。
会设置 isFileChanged 这个字段,最后导出时会判断。
2.通过AssetDatabase.GetDependencies获取依赖信息,把所有的依赖也构建成AssetTarget进行分析。再把这个资源添加到我依赖的资源中,对这个资源添加依赖它的资源,方便后期做冗余剔除。
5.当所有的资源都分析过后。
6.对依赖我的资源进行判断,如果超过2个,就需要单独导出,设置包名。

**d.Export:**导出
导出的过程,就是Buildpipeline.BuildAssetBundles
通过构建AssetBUndleBuild[]数组来构建。而不是直接设置资源的包名。
好处就是如果是git或者svn项目,设置资源的包名就会导致meta文件变化非常不方便多人协作开发。
坏处就是不能直观的看到。

并且采用ChunkBaseCompression的选项,可以加载时实时解压(速度快,官方推荐)。

**e.End:**结束,保存信息
导出完成后,通过加载AssetBundleManifest,获取每一个包的Hash值。

再构建依赖关系表,大概的格式就是:(开发模式采用文本格式,发布模式采用二进制)

结构:
assetPath:用于Editor下加载。
bundleName:记录资源对应的包名。
assetName:记录包内资源名
hash:包的hash值
depCount:依赖数量(如果有,会记录对应数量的依赖的包名,方便依赖加载)

最后一步,就是删除无用的AB。也就是上一次打包存在的,本次打包不存在了。
把本次导出的构建成HashSet,读取打包目录下的所有文件,添加到HashSet。如果添加成功了,就代表本次没有,那就需要删除这个包以及对应生成的manifest文件。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值