优化内容包含:游戏包体积CPU、GPU方面优化、内存优化、其他优化
优化前言
一提到游戏优化,很多人都会立刻想到在cpu和内存上下功夫。但却忽略了最重要的可维护性。。。。。。。(跑题了?没有的事)
因为 编码规范很重要!编码规范很重要!编码规范很重要!
既然是讲优化为何又扯到代码规范?唔,这个话题可能有争议。不过今天不针对这个话题讨论。
不过我这里想引用以下2个著名的效应来应证我要首先提倡编码规范的理论,效应自己意会不做讨论。
破窗效应 |
狄德罗效应 |
推荐书籍:《代码整洁之道》:代码质量与其整洁度成正比。干净的代码,既在质量上较为可靠,也为后期维护、升级奠定了良好基础。
规范建议: 养成不断的批判对待自己代码的习惯,寻找重新组织、改善结构和正交性机会。
优化:
一、游戏包体积优化
1.根据自己的需求选择引擎模块,剔除引擎中不需要的模块。
2.资源优化
声音文件:直接压缩
图片:
1.避免大尺寸的图片出现,纯色图片或有规律的图片用一像素的图片表示
2.带圆角的按钮背景图片用九宫格形式展示。
3.复用一切可复用的资源
4.纹理按功能需求合并,并压缩
plist:可以考虑按需求合并
其他:能压缩、就压缩
Prefab:合理拆分Prefab
注意以下合理性:
1.不能无脑的划分资源模块,需要考虑DrawCall问题,如通用数字资源,再ui界面使用时,如果数字资源不大没直接合并到对应ui的合集图里,避免渲染穿插造成cpu过多消耗
2.如果label内容是字母、常用符号、数字,可以使用位图bmf,并按需求合并到ui中,避免因为label的穿插渲染导致合并渲染被打断。
3.效率、成本。不要花百分之九十的时间、成本去尝试获取百分之一的性能提升。
二、CPU、GPU方面优化
1、概念:
CPU (*处理器) : 通过指令来调度,管理和协调各种不同的任务,处理复杂的逻辑,使用的是串行编程模式。
GPU (图形处理器) : GPU接受CPU的调度,可以处理大量重复的数据集运算和频繁的内存访问,使用的是并行编程模式。
DrawCall : 中文译为“绘制调用”或“绘图指令”。是一种行为(指令),即 CPU 调用图形 API,命令 GPU 进行图形绘制。
2、3者流程关系:
上图只是对渲染管线的部分概括,方便大家理解,实际的图形渲染管线比较复杂,不在本文讨论范围内。
从上图中可以看到在渲染管线中可以看到以下2个流程
1.每一次 DrawCall 前,CPU 都需要做一系列准备工作,才能让 GPU 正确渲染出图像。
2.CPU 的每一次内存显存读写、数据处理和渲染状态切换都会带来一定的性能和时间消耗。
理解了3这的工作原理和关系后,我们来看一下流程瓶颈:一般来说 GPU 渲染图像的速度其实是非常快的,绘制 100 个三角形和绘制 1000 个三角形所消耗的时间没差多少。但是 CPU 的内存显存读写、数据处理和渲染状态切换相对于 GPU 渲染来说是非常非常慢。所以实际的瓶颈在于 CPU 这边,大量的 DrawCall 会让 CPU 忙得焦头烂额晕头转向不可开交,而 GPU 大部分时间都在摸鱼,是导致游戏性能下降的主要原因。
渲染优化:
1.按功能或者按需求合并图集。
2.按需求合并部分文件,减少io。
3.严格控制渲染节点树。相邻渲染节点尽量来自同一个图集,特别是再循环中创建的节点树。
4.限制底层绘制分辨率。
5.控制游戏帧率。
6.降低逻辑复杂度。
7.减少Mask、spine 等能打断合并渲染的组件使用。
8.逻辑比较复杂或者节点较多的界面,采取分帧加载,避免一帧内执行过多操作,导致这一帧压力过大。
9.优化节点树,尽量减少节点数量。
10.如果label内容是字母、常用符号、数字,可以使用位图bmf,并按需求合并到ui中,避免因为label的穿插渲染导致合并渲染被打断。
11.减少频繁创建与销毁
12.合理规划 Material(材质)、Blend(混合模式)的变更(如自定义Shader ),会导致合并渲染被打断
内存优化:
1、优化图集,最大限度填满图集,不要留有太多空白
2、大尺寸的图片改用九宫格
3、静态资源的内存管理:
静态资源指的是场景中直接或间接引用到的所有资源(脚本动态加载的资源不算在内)。
在场景资源的属性编辑器中可以勾选“自动释放资源”选项,从而在切换场景时,会自动将旧场景使用的静态资源释放掉,从而节省内存的占用。
4、动态资源的内存管理:
动态资源统一使用cc.loader进行资源的加载以及管理。参考:动态加载要注意的一点是,CocosCreator中通过cc.loader去加载资源的所有方法,都是异步的。所以需要在回调中,确认加载完成后才能使用资源。也可以通过cc.loader.getRes这个API去同步的获取资源,但需要对get到的资源进行检查,如果没有加载或者没有加载完成,则需要等待或者通过cc.loader进行加载。
5、label优化之共用离屏的Canvas(只针对h5、小游戏,代码以cocos-js 3X为例):
//修改CCLabelTTFCanvasRenderCmd.js文件中的文本渲染依赖为共用一个canvas而不是每一次都去创建
var sharedLabelCanvas = null; cc.LabelTTF.CacheRenderCmd = function () { this._labelCmdCtor();
sharedLabelCanvas = sharedLabelCanvas || document.createElement("canvas");
this._labelCanvas = sharedLabelCanvas;
this._labelCanvas.getContext("2d").clearRect(0, 0, this._labelCanvas.width, this._labelCanvas.height);
this._labelCanvas.width = 1;
this._labelCanvas.height = 1;
this._labelContext = this._labelCanvas.getContext("2d");
};
其他优化:
1.压缩和转化文理格式(h5安卓可以考虑使用webp可以参考我的另一篇博客:https://www.cnblogs.com/xyptechnology/p/10983233.html)
2.游戏流程优化 参考我的另一篇博客中的流程优化:https://www.cnblogs.com/xyptechnology/p/11996591.html