您的位置:首页 > 移动开发 > Unity3D

浅尝Unity 3D的Asset Bundle知识(六)-----缓存利用进阶篇

2015-08-05 15:10 330 查看
经过了缓存利用相关的理解,小生对于Unity的Asset Bundle的研究也将更加深入。今天就让我们进入关于缓存使用进阶的讨论吧。

说到缓存使用,我们已经知道了如何使用Unity来把Asset Bundle保存在缓存中,同时据小生学习了解,一个app的最大缓存空间是4GB。问题就来了,如果文件过多的话超过了这个上限大小的时候怎么办,这是第一点。第二点是如果我想每个开发者而言膨大的app对使用者来说都不是很友好,例如说一个用户如果没有太多钱买了个16G版本的iPhone的话,按照一个经典游戏来说2GB的话,那他最多能装下8个游戏(在这个游戏不继续更新的情况下),那是不是意味着这个用户想玩我们游戏的话那如果在空间过小的时候他就势必要删除一些占用空间的资源。那首当其冲的就是那些空间占用大户了。同时我们游戏不幸不是太被对方中意的话(外加网上评价说游戏下载长期使用后占用资源过大的话),恐怕就会有那个用户索性不下载的风险。或者说如果我们的游戏现在用户的机器上,用户想要急于尝鲜新的游戏的话,那我们的游戏过大的话那也有可能被用户无奈地删除掉了(小生一般都是删除掉感觉不玩也可同时占用空间过大的app)。

小生也是经常在考虑这个几个问题,小生认为Unity给我们提供Asset Bundle是为了节省初期下载时候文件过大以及解决动态更新的问题,但是只是注意到这些优点而不关注弊端的话,很可能造成了反作用的效果,这样的话最后本来很好的一个功能就会在一定程度上成为了一个定时炸弹。

所以针对以上问题,小生也在想如何去规避这些问题,想好了就要和大家分享交流不是,如有欠缺之处还请各位看官多多包涵了指正。

在下文中,小生会具体从1.下载 2.缩小缓存占用空间 这2个方面来阐述小生的解决方案。

1.下载 :

下载Asset Bundle的方式在上篇文章已经提过小生就不在此处多多阐述了,用到的是WWW.LoadFromCacheOrDownload,那么这个函数会更具传入的version来判断是否需要重新下载新的文件,小生做了一个实验,下载同一个path的Asset
Bundle,第一次version为0,第二次为1.然后再去下载version为0的时候会产生什么效果?

小生之前有个误解,以为version为1的这个文件下载的时候会去替换version为0的文件。但是结果却是和小生想的大相径庭。两个version的文件都会保存在缓存当中,version为0的文件不需要重新下载。关于这个实验主要使用的是一个Api Caching.IsVersionCached

关于这个Api的用法就是传入Asset Bundle的path和version来判断是否已经保存在缓存中了。看到这种结果,我想各位看官和小生一样可能会想了,如果这个资源包有十个版本的话,那不就在缓存中存了10个相同path的文件了么。Yes,You are right!

2.缩小缓存占用空间

基于上个问题,小生就想到能否可以解决这个问题,与之而来的就是这个第二点。具体方式就请听小生慢慢道来。主要有以下几个策略。

1. 减小Asset Bundle缓存的大小

每个App都是有自己的Asset Bundle的空间的,这个大小上限为4GB的,如果这个空间不被超出或者没有超过其失效时间的话,那么相对老版本的Asset Bundle文件是不会被Unity的自动缓存管理机制(LRU)来去清除的。

LRU(Least Recently Used)的管理机制就是Unity给每个Asset Bundle文件都加上一个计数器,被访问一次就给加上1(这个地方小生感觉和Objective-C中的自动内存管理(ARC : Automatic Reference Counting)很相似),当要清除的时候去删除掉计数相对小的文件。

基于这个原因,我们就不能等Unity的LRU来做清除了,小生开始查找文档看能否通过下载一个path的Asset Bundle文件的时候如果发现是新版本的话就把缓存中对应的旧版本的文件删除掉,但是很可惜小生没找到有支持这个想法的Api。最后小生发现了一位仁兄的方案,也是小生认为比较靠谱的方案吧,那就是通过设定App的缓存空间的大小来达到这个效果。实现的方法就是通过设置Caching.maximumAvailableDiskSpace的值来达到限制缓存空间的大小。但是这个方式也有一个弊端那就是如果设置的不合理的话,就会发生需要经常重新下载Asset
Bundle文件问题。

2. 缩短Asset Bundle的失效时长

其实第一点已经提到了,也可以通过设置Asset Bundle的有效时间来让LRU去清理不需要的Asset Bundle,说得简单点的话第一点的方案就是强制设定大小上限来出发Unity的LRU,而这个方法就是设定一个定期清理的时间,让Unity的LRU执行。实现的方法就是通过设置Caching.expirationDelay这个值。

3. 尽量利用Dependency来打包Asset Bundle,从Asset Bundle的总体容量上下手

这个方法其实小生推荐如果这个方式不好用的时候再去用上两个方法来去继续优化,因为如果没有一个继承结构良好的Asset Bundle的组织话,上面两个方案产生的效果小生个人感觉是治标不治本的。如果有一个好的继承树,这样就可以通过Dependency的方式来尽量缩小每个Asset Bundle的file的大小,从而在根本上达到缩小Asset Bundle总体大小的目的。至于Dependency这个地方,小生会在下一篇的文章来和各位看官交流其使用方式,如果各位看官感兴趣的话,还请多多关注噢-----Dependency进阶利用!


上面就是小生最近关于Asset Bundle相关知识的所研究所想的一些内容(比起本文的解决方案,可能各位看官还有更独到的方式,还请多多指教和拍砖啊),但是发现这个只是针对打包的一些解决方案,但是看了很多Unity开发人员的经验谈后发现只是在打包上做文章还不够,还有读取的优化,譬如说只把需要多次读入的以及共通的东西缓存上等等办法。看来小生在相关方面还是需要继续耕耘啊~路漫漫啊,但是小生会坚持不懈把这些细的知识点争取慢慢一点一点去攻破!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: