Unity性能优化记录——协程的性能消耗

前言

在项目开发中,经常会用到UI动画效果,因此做了一套UI动效工具,能够满足大部分使用,该工具底层采用协程驱动动画播放,带来的后果是每一个UI想要有动画都得需要挂一个动画组件,而每个动画组件运行时都至少会开启一次协程去驱动动画效果播放,如果有需求要同时在一个页面使用很多的item并且每一个item都有独立动画,那就会造成较大的性能消耗。本篇文章记录如何解决以上的问题。

主菜

设计思路

原有的设计思路围绕oop原则,某个对象需要这个效果就带一个对应效果的组件为其服务,思路如下:

  • 设计一个模板类,核心功能是具备一个计时器能够指定时长去驱动动画。
  • 提供一个数学缓动函数库,输入[0-1]之间的播放进度值,返回对应的系数值。
  • 实现4种不同属性的动画行为(旋转、缩放、位移、透明度),每一个以子类的方式实现(可扩展)。
  • 根据需要挂载不同类型的动画效果,可复合使用

优点:使用极其方便,直接挂在对象上,设置自动播放、播放时长、效果等等,也可以代码控制。
缺点:当场景中使用较多动画对象时,会变得卡顿。

极端测试

通过代码创建10000个带旋转动画并设置循环播放的UI对象后变得极为卡顿:

    public void Create() {
        for (int i = 0; i < 10000; i++)
        {
            var e = Instantiate(templateMethod, root);
            e.isLoop = true;
            e.Play();
            easyAnimationTemplateMethods.Add(e);
        }
    }
协程模式下大量动画

(这里由于图片渲染的关系,其实帧率降低与大量协程并不是直接因素)
在协程模式下驱动器每一帧都会执行,打开Profiler查看更是夸张。。。


prodiler下的性能监视

可以看到,所有协程每一秒都在疯狂的产生GC, GC Alloc达到了195.3kb,如此恐怖的数值,一般来说手机上几k都会造成明显卡顿了,更不用说上百。
协程虽然方便,但这就是一个典型的反面教材。

解决思路

将原来的每一辆车都有一个发动机思路做一个大胆的改动
一个超级发动机驱动多台车辆!!!
这就让人懵逼了>...< 我一台发动机怎么给多个车用,简直疯狂。
在我第一次接触ECS设计模式的时候就是这样的,不能理解!!!
其实在ECS的世界中上面的比喻有一点问题,需要改一下:
ECS里面应该是汽车需要能源驱动,我现在有一个能源系统,能源系统会给所有能够接受能源的机器源源不断的提供能源,不管是车辆还是工厂里面的机器,如何运转在于机器自己如何使用这个能源。
那再来看看原来的模式下在ecs中是怎样的:
每一辆车都装了一个能源系统,将产生的能源驱动给自己的发动机中然后开起来了,这样就导致每一辆车的成本实在太高了。。。。而且过于浪费
在Unity里我的能源系统不能方便的找到世界中所有需要能源的机器,于是需要改动一下,改成需要能源的机器主动找能源系统登记。

以上是自己的一个简单比喻,现在大致找到原因是车辆成本太贵,因此只需要去掉原有的第一步,并改为:

  • 创建一个能源系统,有一个登记处,所有需要服务的机器都过来登记,到时候按照登记表提供能源

以上是改进的核心思路,总结一下就是由原来的各自独立驱动器改为一个全局驱动器驱动所有动画,代码不详细提供。
直接看Profiler运行的监视信息:


全局驱动模式

可以直观的看到GC带来的性能消耗显著降低,由之前的195.3kb 降低到了 20b,帧率也由10几帧提高到了接近30帧左右(当然前面说过真正严重影响帧率的是渲染部分导致),仅gc的优化带来的帧率提升是非常客观的了。
在进一步优化:由于驱动器只需要每一帧去调用不需要严格的时间等待,因此可以抛弃协程,改为一个全局的Update,可以进一步优化性能:


Update全局驱动模式

如此一来动画系统直接没有GC产生了,动画系统的性能问题宣告解决!

最后的改进: 每一辆车需要用的时候都要去登记一次,显得有些麻烦,因此保留了原有的自驱动模式,通过判断是否使用公共驱动来动态决定用那一套,这样也满足在开发过程中有一些简单页面依旧可以像原来的方式需要什么效果直接挂组件就行了。

最后的最后

以上的主角是自己的一个UI动效小插件EasyAnimation,已经开源在我的git上,希望支持star一波:EasyAnimation

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,271评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,725评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,252评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,634评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,549评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,985评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,471评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,128评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,257评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,233评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,235评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,940评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,528评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,623评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,858评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,245评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,790评论 2 339

推荐阅读更多精彩内容