注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

重新出发的阿赵

阿赵的博客

 
 
 

日志

 
 

项目优化的得与失  

2017-12-24 22:09:35|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
每次做项目,项目的制作人也会经常和你提起,你看某个游戏才100多M的包体,另一个游戏加载一个场景只需要1秒,再另一个游戏,整个游戏都是PBR材质,画面非常精美。这时候你可能就会很迷茫了,为什么别人能做到了,自己不能做到呢?也许你没有看到的是,100多M的游戏,其实是在后台偷偷的下载资源,可能会由于网络原因导致资源加载不到或者被用户发现而引起反感;场景加载需要1秒的游戏,其实只加载了主角附近的一小块,后面的都是根据位置慢慢加载的,如果一开始没有做好场景加载策略的规划是很难实现的;整个都是PBR材质的游戏实际上包体容量有1G多……
这是一个很哲学的问题,摆在开发者面前的有这么2个因素是无法改变的:
1.用户的机器性能,面对的用户群体不同,就要考虑不一样的硬件性能。如果需要任何用户都能玩得正常,要么以最低标准来定硬件性能,要么有好的策略把游戏质量分成几个档次。
2.时间和空间的相对关系。一般来说,这cpu和gpu的性能恒定的情况下,加载和处理的时间也是恒定的。如果想看起来加载得比别人快,一般就只能用空间换时间。也就是常用的用内存多缓存对象,甚至预加载对象,达到不需要在重要的时候因为加载卡住。
所以很多问题都是相对的,有得也有失,这做策略的时候需要懂得取舍。
举一个场景加载的例子。
最近我在做一个项目。这个项目是建立在公司另外一个团队的项目基础上的,所以使用的是别人的框架。这个团队的框架加载场景是直接使用了LoadLevel的方式加载整个场景的。之前团队的做法是,场景完全不打任何依赖,每个场景就是一个AssetBundle,需要加载场景的时候就直接LoadLevel。接手这个项目之后,我做了一些修改,把场景变成打依赖,这样场景与场景之间重复用的资源越多,就越省包体容量。但我又发现了Unity的一个Bug,在把一个Scene打包成AssetBundle的时候,如果只是打包一部分依赖,场景里面似乎会保留了那些没有打依赖的资源在里面,导致了打一部分依赖之后,所有场景加起来的容量变得比所有场景完全不打依赖还大了一百多M。这就导致了我原来的大于2的引用的依赖才打包的策略就不能实现了。所以我只能把他们的依赖拆得最散。
在这个阶段,项目请了专家来分析优化性能。其中一个意见是,AssetBundle如果使用LZ4的压缩方式,会比使用默认的Lzma方式压缩,在加载的时候快6倍。于是我又把打包AssetBundle的压缩方式改成Lz4.结果加载速度的确是快了,但打包出来的AssetBundle容量却大了一半多,从原来的300多M资源变成了500多M。然后项目制作人说平台那边对容量有要求,说买量的时候,包体大会花多很多钱,所以我还是又把资源改为了Lzma了。
这第一种场景完全没有打依赖,lzma压缩的情况下,包体大概是480M左右,首次加载某个场景大概是4.5秒左右。
第二种情况,场景完全打依赖,lzma压缩的情况下,包体大概是370M左右,首次加载同个场景大概是4 秒左右。
第三种情况,场景完全打依赖,lz4压缩的情况下,包体大概是600M左右,首次加载同个场景大概是2.5秒左右。
以上的结果都是同一台手机,退出游戏反复进同一个场景3次,算出的平均值。
可以看到,完全不打依赖的情况并不会真的比完全打依赖的快,而且由于AssetBundle之间有冗余,导致包体也会变大。
Lz4的确快,但容量却大很多,如果不考虑平台买量压力的情况下,是一个不错的选择。
其实还有最后一种手段,就是AssetBundle完全不压缩,然后自己把资源打成Zip包放到StreammingAssetPath里面,当游戏首次安装启动的时候,先从包内把压缩包拷贝到手机内存里面,然后解压缩。这样加载就最快了,而且包体可以做得最小,上苹果的Appstore也不怕包体变大。带来的缺点是,首先,解压缩之后会占用很大的用户手机硬盘,加上安装包内的压缩包是无法删除的,可能一个本来600M资源的游戏,就要占用用户手机1G以上的硬盘空间。然后在游戏安装的时候,解压缩的时间可能会很长。最后一个问题是这样自己打zip包,会导致热更新的策略受到限制,起码就不能散放文件对比版本号,必须把每个版本的变动资源打成单独的zip包作为补丁包,这样跨版本更新的时候就比较痛苦。
所以在策略没有出现问题的情况下,想做好一件事,往往需要放弃一些事。lz4是快,但如果关心包体容量,可能你就要放弃那1秒多的加载时间了。
不过这也不能是作为放弃优化的借口。很多时候遇到这些问题,是因为一开始的策略没有定好。就像我遇到的问题,假如一开始不是在别人的框架上开发,我也不会选择LoadLevel的方法来加载场景,我一直的选择都是通过拆分场景,把一个Scene拆分成很多预设和一个场景配置文件。加载场景的时候都是按照配置逐个加载模型,然后手动指定LightMap等参数等。这样的策略下,优化的方案就很多了,比如先生成地形和主角,附近的人再逐步生成,就可以把切场景的loading时间变得比较短。
  评论这张
 
阅读(173)| 评论(0)
推荐 转载

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018