Unity5的Bundle开发和优化

Unity5的Bundle开发和优化

https://gameinstitute.qq.com/community/detail/128107

一、关于Bundle加载速度图示:

 

二、设计方案:

 

有两种方案可供选择:

 

第一种是用完全bundle的管理方式,以每个文件夹作为独立的bundle,项目管理过程中需要注意分包处理、在加载Object和场景之前先加载其相关依赖的bundle,场景切换前卸载上个场景不需要的bundle。然后在加载和卸载的过程自己去给每个文件单独计算引用计数。最后提供当某些资源不用之后,可以卸载其缓存资源和bundle。特点是原生的bundle加载方式便于理解和管理,但是引用计数(不一定和Unity的计数完全一致)存在隐患。

 

第二种方式,是用自定义文件格式去处理,打包bundle的时候,把每一个资源单独打包成bundle,然后再根据自定义把所有bundle打成一个或多个Page包,然后通过id length offset去读取每个bundle文件的内容。在加载的时候可以用多线程去读取资源,然后在主线程创建bundle和资源。特点:复杂度稍微高一点,bundle分的很散便于引用计数的计算和内存管理,但同时过散的资源也可能导致速度问题。另外后台多线程会提高文件的读取速度,但同时增加缓存读取和内存创建bundle 可能带来额外的内存开销。

 

三、其他:

 

LZMA:Unity打包成AssetBundle时的默认格式。优点是打包后体积小,缺点是解包时间长导致加载时间长。

 

LZ4:相较LZMA会生成更大的压缩文件,但优点是使用时不需要整体解压

 

BuildAssetBundleOptions.None|默认LZMA方式压缩

BuildAssetBundleOptions.UncompressedAssetBundle |不压缩资源,最后可以使用自己的压缩方式

BuildAssetBundleOptions.CollectDependencies | Unity5.3不用了

BuildAssetBundleOptions.CompleteAssets |Unity5.3不用了

BuildAssetBundleOptions.DisableWriteTypeTree | 不能无视TypeTree的改变,如果TypeTree发生了改变

BuildAssetBundleOptions.DeterministicAssetBundle |编译资源包使用一个哈希表储存对象ID在资源包中。

BuildAssetBundleOptions.ForceRebuildAssetBundle | 强制重现生成bundle,即使bundle没有改变。

BuildAssetBundleOptions.IgnoreTypeTreeChanges | 可以无视TypeTree的改变,即使TypeTree发生了改变

BuildAssetBundleOptions.AppendHashToAssetBundleName |把Hash导在bundle的名字中

BuildAssetBundleOptions.ChunkBasedCompression |用Lz4的方式进行压缩

BuildAssetBundleOptions.StrictMode |严格模式,有任何错误产生 马上终止打包。

BuildAssetBundles的AssetBundleBuild[]参数和面板上的AssetImporter参数差不多 , 都是提前设好bundle名字和Variant名字。

 

内存来说loadbundle比loadAsset远小

设置相同assetBundleName的打包到同一个bundle资源里边。设置相同的assetBundleName和assetBundleVariant打包到同一个assetBundleName.assetBundleVariant资源里边。

设置相同assetBundleName和不同assetBundleVariant的 会被认为是同一个bundle 不能重复加载(只能先卸载) 他们之间不能有依赖关系,但是bundle文件分开是多个。常用来做不同精度的模型或者贴图分开显示。

依赖关系只跟assetBundleName有关。可以只使用assetBundleName进行bundle分包,只有把prefab material texture shader等全部分开打成bundle才能不会资源重复,否则一个bundle会将所有依赖的资源打在一个包里。

注意IOS文件限制和每个bundle包的大小,不能太大。

 

加载策略:

采用多种策略加载:慢速加载:纯异步:load bundle和loadAsset都异步,Resource异步加载

快速加载:半异步:load bundle同步和loadAsset异步,Resource同步步加载

正常情况,快速加载比较快,但是大资源Resource内文件异步比同步速度快,小资源相反。(说明异步加载确实是多线程了)

 

缓存策略:

bundle模式有三种文件缓存,分别是:

bundle文件:可以理解为文件系统的原始二进制数据,加载速度很快内存消耗比较小。缓存在bundleManger

Asset文件:经过二进制文件创建出来的资源文件,包括声音图形mesh等缓存文件,加载速度根据创建对应资源的类型不同会慢一点。缓存在ResourceMgr

场景文件:实例化的场景文件及其引用,缓存在游戏中

 

卸载特点:

1.bundle的加载几乎没什么消耗只是部分依赖数据的加载。所以内存优化重点是ResourceDB

2.bundle.unload(false)只卸载bundle会导致缓存资源冗余,bundle.unload(true)会完全卸载 但是如果场景中还有引用,资源会丢失。

3.GetAllDependencies 会把该bundle内全部资源的全部依赖的bundle加载进来,如果bundle划分不是很细的话会加载冗余数据,依赖关系最好自己维护。

4.bunlde中缓存资源一旦加载,若其依赖的资源被卸载后再加载 该资源依赖丢失不可用,若只是本身bundle卸载再创建,可用重复加载资源,因为每个资源的依赖资源是存在本身身上的。

5.Unity正常切换场景会把下个场景没有引用的资源卸载掉,引用包括bundle引用,ResourceDB引用,场景不卸载的OBJ引用。

6.我们的逻辑切换场景的时候会把下个场景不用的所有资源和bundle卸载掉,但是对于下个场景要用的bundle但是其中的某个资源已经不用了,无法卸载(就算场景和ResourceDB引用置空也无法卸载),这种时候建议分成不同bundle。

 

卸载策略:

1.场景文件加载后其和依赖的bundle不能卸载,否则容易内存冗余和出错。直到再次切换场景把上一个场景中的所有存在bundle根据条件给卸载掉。

2.对于全局存在不被依赖的Prefab,可以加载后存在场景中设置DontDestroy,然后把ResourceDB置空,把该prefab的bundle.unload(true)卸载该prefab。这样内存最优,但是不能卸载其依赖的bundle,然后要保证其他地方不会再load该资源。

3.主要优化是卸载ResourceMgr的数据 ?而不是bundle,bundle的内存占用很小。采样unload(true)策略。

4.场景加载后的场景bundle和其依赖bundle一定不能unload(false),单纯卸载bundle的意义不大,最好是直接操作unload(true),但是要管理好资源,容易出错。

5.相同多的Object,放在场景里加载比单独加载Prefab快。

6. Resources.UnloadAsset(mat);这个只能卸载Texture等资源,prefab等实例资源 只能Destroy(obj),缓存Obj资源无法手动卸载,只能把引用置空切换场景和bundle.unload(true)卸载掉,然后Unity就会自动释放。

7.建立一张单个资源的依赖和被依赖资源

8.要么unload(true),要么所有bundle都不要卸载。想卸载资源就要解决依赖问题。unload(false)比不卸载更可怕。

 

优化策略:

1.对于特定资源比如主角职业相关的技能技能特效装备等,在整个游戏过程中会反复加载的,那么在高内存机器上设置不卸载,bundle和ResourceDB都不卸载。预加载并且不卸载。

2.对于全局UI和全局主角,加载后,把其Object的bundle和ResourceDB给卸载掉,然后GameObjec设置DontDestroy永远存在,其依赖的资源不能处理。

3.设置bundle的不卸载会导致该bundle所有资源和所有依赖的资源都不卸载,如果把其依赖给卸载了,就算再加载 该bundle的依赖也是丢失的,只能把该bundle再卸载了重新加载。?

4.不卸载的优化只能从美术规范上去规避,只能单独的少量资源设置不卸载。要保证bundle内全部资源都是可以不卸载的。

5.设计通用UI管理器,跟EffectPool方式一样去管理。

 

依赖测试:

1.prefab依赖测试:

 

2.场景和prefab的依赖

……So……bundle的增量打包一定要定期清理bundle,全部删除重新打。

 

3.场景和普通资源的依赖

结论就是:不能采用prefab依赖的方式打包,一定要采用细分原则,把所有用到的资源都标记独立打包。

 

参考:我们以前游戏是使用美元符号$来标记,该资源或者该文件夹内资源独立打包成一个bundle。另外要定期清理所有bundle。

来自:https://blog.csdn.net/gy373499700/article/details/79508842

 

 

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值