前言

优化从来不是凭感觉去看代码,而是利用有效的工具,去测出游戏的性能瓶颈,然后找到解决方法。 最近在给一款游戏做CPU优化,就把过程记录下来,分享一下,欢迎纠正讨论。

查找性能的瓶颈

工具的选择

mac下使用xcode自带的Time Profiler(win下可以使用vs)

开始分析

大概观察下

首先用xcode->Product=>profile,完成后选择Time Profiler,然后跑一段时间,你可以得到下面类似的分析报告 在这边我们可以查看那些占比高的项,这边我们看到cocos2d:Director::drawScene是cocos的主线程的消耗,然后 一层层往下看会发现cocostudio::timeline:ActionTimeline这边占用了24.2%,这部分是cocostudio里面的动画 带来的消耗

针对性观察

就从动画开始入手吧,我们进游戏看动画的数量,选择性的增加和减少动画的数据,然后再进入Time Profiler观察数据 的变化(这边我并不想插入太多图片,希望大家多动手,我也懒得截图),很容易就会发现这个数据随着动画数量和时间累加 比重会一直往上走,说明这个点是影响CPU比较大的点

方案选择

减少更新内容

找到问题相对是比较简单的,方案是本文主要讲的内容,不同游戏的方案是不一样的,我主要是讲方法和思路,从上面数据我们 可以得出主要是动画的更新带来的消耗,那么现在主要解决的问题是“如何减少更新内容?”仿佛会听到美术和策划说:“减少是不可能减少的”,减少动画也不是我们的首选,优化的思想主要还是以不影响效果,除非这个 影响级别能够打动BOSS,那现在的问题进一步转化为“哪些动画是不必要更新的?”

不更新不必要显示的动画

屏幕外的动画不更新

细心的同学可能会去测试下屏幕外的动画会不会更新,答案也是肯定的,所以这部分我们是要干掉的

void ActionTimeline::step(float delta)
{

    if (outOfScreen)
        {
            return;
        }
  ...
}

不可见的动画不更新

void ActionTimeline::step(float delta)
{

    if (isVisible == false)
        {
            return;
        }
  ...
}

被挡在后面的动画不更新

前面两点应该是比较好处理的,后面这个可能就需要一套机制来支持,在游戏中经常会叠加多个界面。 情况一:叠加的界面是一个全屏的界面 这种情况直接把下面的全隐藏即可,不会影响任何效果 情况二:叠加的界面是多个非全屏的界面(一般这个界面会有一个黑色遮照) 这种情况可以考虑只保留一个底(这个底就是一个全屏的界面),然后再保留最上层的界面即可。当然光这样操作 还是不够的,因为这边的底可能还是有不少动画,而且这个时候我们其实并不关心这些动画,我边会针对不一样的 底做不一样的方案,如果是动画少的可以不处理,如果主要集中在中间的可以考虑隐藏动画,最后一招就是把下面 整个底用RenderTexture绘制成一张图(这招会有一些坑,后面补充)

总结

做完这些后,你会神奇的发现除了CPU占用下来了,GPU也降了许多,原因就是你把那些隐藏掉了后,渲染的对象也减少了 许多。