NGUIjs 会消耗服务器性能了大量的性能,怎么破

To be an elegant coding girl...
Unity学习小结4 -
NGUI的几点性能问题
沉默了好长时间,也忙了好长时间,起始也 是一直在为自己没能好好的总结和思考找借口,想总结,时间总还是能抽出来的。最近积攒的坑感觉差不多够多,往出倒上一部分,也相当于为自己今后解决问题多留一些注意点。很多地方写的不准确和错的,还希望大家能够帮我指出。
1. 滚屏组件UIScrollView低性能问题:
如图是我们实现一个带子节点元素的滚动屏幕,括号 中的组件为非必须,像如果想要实现带点击事件的话,UIDragScrollView节点上就得挂上button脚本了。我之所以把结构画出来,是因为在UIScrollView和UIDragScrollView看似职能不一样的脚本中做了很多“重复”的事情。UIScrollView里有OnPress、 OnDrag的事件嵌套调用,这些都不是问题。为了实现拽的效果,UIScrollView的LateUpdate里还添加了一些后续的处理包括重调OnDrag,使得如果我们添加UIScrollView的OnDragFinish事件的话,该事件会被执行两次。而且LateUpdate里的调用会有明显的延迟,两个OnDragFinish事件间隔时间间隔较久。我个人不需要“拖拽”的效果,就将LateUpdate中的OnDrag
去掉。目前暂未发现有影响的BUG。
2. OnDragScrollView的BUG:
同样是上面的设计,我们可以实现一个翻页的滚屏。但是通常的设计是UIDragScrollView的组件是一页。但是如果我每一页中有多个UIDragScrollView呢?每个元素控制的坐标范围就不够一屏。这种情况下是没法直接全屏翻页的。。比如MoveRelative之类的,直接失效,最后只好暴力的指定上下页的元素。所以说NGUI其实还有很多不完美的地方,等着我们用心去发现和逐步的优化。
扫码向博主提问
Unity,C#都来
擅长领域:
没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!手游实时PVP帧同步解决方案–客户端
手游实时PVP帧同步解决方案–客户端
编辑日期: 字体:
最近的一款手游《王者荣耀》大家玩的挺火的,给腾讯带来几十亿的月流水。大家或许知道 王者荣耀 是用Unity3D开发的,也知道王者荣耀是用帧同步的解决方案,网络传输用UDP传输协议,为什么要这样做上次孙勋(。
本文主要探索PVP帧同步解决方案。
1.1、基于UDP的帧同步方案
在技术选型方面,之所以选择帧同步方案,在Kevin的一篇介绍PVP帧同步后台实现的文章中已经做了详细叙述,这里简单摘要如下:
高一致性。如果每一帧的输入都同步了,在同样的上下文中,计算得出的结果应该也是同步的。
低流量消耗。除了帧同步,其它方案(比如状态同步)想做到高一致性,需要同步非常大量的数据。无论是对于移动网络,还是固络都是不合适的。
服务器逻辑简化。采用帧同步方案,服务器只需要做简单的帧同步,不需要关心太多的业务细节。有利于客户端功能的扩展和服务器的稳定和性能。
反作弊。客户端只需要在适当机时上报校验数据给服务器,服务器对2个客户端上报的数据进行对比,就可以快速识别是否有人作弊。然后通过无收益的方式间接防止作弊。
那么,为什么选择UDP而不是TCP呢?主要有2点原因:
弱网络环境。
实时性要求。
我们通过一个测试APP,在WIFI和4G环境下,采用TCP和UDP两种方式连接同一个服务器,分别获得对应的RTT进行对比。
我们可以发现,在弱网络环境下,UDP的RTT几乎不受影响。而TCP的RTT波动比较大,特别是受丢包率影响比较明显。
1.2、基于UDP的FSP协议栈
由于UDP具有不可靠性,所以在UDP的基础上实现一个自定义的协议栈:FSP,即FrameSyncProtocol。
FSP的基本原理就是防照TCP的ACK/SEQ重传机制,实现了传输的可靠性,同时还采用冗余换速度的方式,又保证了传输的**速率。在帧同步方案中一举两得。
2、技术原理
2.1、帧同步技术原理
如下图所示,客户端A的操作A1与客户端B的操作B1封装成OperateCmd数据发送给PVP服务器。PVP服务器每66MS产生一个逻辑帧,在该帧所在时间段内收到A1和B1后,生成一个Frame数据块,在该帧时间结束时,将Frame发送给客户端A和B。Frame数据块内有该帧的帧号。客户端A和B收到Frame数据后,便知道该帧内,客户端A和B都做了什么操作。然后根据收到的操作A1和B1进行游戏表现,最终呈现给玩家A和B的结果是一致的。从而实现客户端A与B的数据同步。
图1 帧同步技术原理
2.2、FSP协议栈原理
如下图所示,发送者维持一个发送队列,对每一次发送进行编号。每一次发送时,会将待发送的数据写入队列。然后将队列里的数据+编号发送给接收者。
接收者收到数据后,会将该编号回送给发送者以确认。发送者收到确认编号后,会将该编号对应的数据包从队列中删除,否则该数据仍保存在发送队列中。
下次发送时,会有新的数据进入队列。然后将队列中的数据+最新的编号发送给接收者。以此循环反复。
图2 FSP协议栈原理
上图解析:
第1次发送,在发送队列里只有Data1,于是将Data1和编号1(Seq=1)发送给接收者。收到确认编号1(Ack=1)后,将Data1从队列中删除。
第4到7次发送,由于从第4次发送开始就没有收到确认编号,于是队列中包含了Data4到Data7。第7次发送后,收到确认编号6,于是将Data4至Data6从队列中删除。
第8次发送,队列中包含Data7和Data8。发送后收到确认编号8,从而将Data7和Data8从队列中删除。
以上的关键点是,发送者未收到确认编号,并不一直等待,而是会继续下一次发送。结合图1:
如果发送者是服务器,则会每隔66MS会将一个Frame数据写入发送队列,然后将该队列里的所有Frame数据一起发送给客户端 。
如果发送者是客户端,则会在玩家有操作时,将玩家的每一个OperateCmd数据写入发送队列,然后将该队列里的所有OperateCmd数据一起发送给服务器 。如果发送队列不为空,则每隔99MS重复发送。如果发送队列为空,则不再发送。直到玩家下一次操作。
由于服务器和客户端即是发送者,又是接收者。则服务器和客户端的每一次发送,除了会带上该次发送的编号,还会带上对对方发送编号的确认 。
3、技术实现
3.1、整体框架
图3 PVP通讯模块整体框架
这是一个典型的手游PVP通讯模块的整体框架。这里主要分享一下FSP模块和帧同步模块的技术实现。
3.2、FSP模块
FSP模块主要用来实现FSP协议栈。其协议格式定义如下。
FSP上行协议定义:
OperateCmd List
FSP下行协议定义:
Frame List
如下图所示,是FSP模块的接收逻辑流程。
图4 FSP模块接收逻辑流程
其中关键点是:
对Recv New Ack判断,对曾经发送过的Operate进行确认删除。
  对Recv New Seq判断,过滤掉因为网络问题造成乱序的包。
上图中,接收到的Frame最终都存储在RecvQueue中。我们将接收逻辑放在子线程中。所以只需要在主线程中需要Recv的时刻从RecvQueue中读取FremeList即可。
如下图所示,是FSP模块的发送逻辑流程。发送逻辑同样放在子线程中。发送逻辑有2种触发方式:
业务层主动调用发送
每隔指定时间触发一次(在WIFI和4G下使用不同的时间,可以减少服务器收到的纯确认包比例,有利于提高通讯性能)
图5 FSP模块主动发送逻辑流程
图6 FSP模块定时发送逻辑流程
3.3、帧同步模块
下图是帧同步模块的实现框架。
图7 帧同步模块实现框架
按照上图箭头编号描述如下:
(1)负责接收来自FSP模块的FrameList。
  (2)将FrameList里的每1帧都存入FrameQueue。
  (3)同时将FrameList的每1帧的帧号进行变换后,得到客户端帧号。同时,在等下1个服务器帧到来之前,需要将客户端的帧锁定在下1个服务器帧的前一帧(LockFrameIndex)。然后 将FrameIndex和LockFrameIndex传入FrameBuffer。
  (4)客户端每1帧从FrameBuffer中取出当前可能需要跳帧加速的倍数(SpeedUpTimes)。
  (5)如果SpeedUpTimes为0,则表示正在缓冲中,没有需要处理的帧。如果SpeedUpTimes是1,则表示缓冲结束,但是不需要加速,只需要处理最新的1帧。如果SpeedUpTimes大于1,则从FrameQueue里取出这SpeedUpTimes个帧, 将里面的SyncCmd取出来。
  (6)将SyncCmd传入OperationExecutor。
  (7)OperationExecutor与具体游戏的业务逻辑相关联,负责将SyncCmd传入给业务逻辑和预表现模块进行具体的处理。
其流程图如下:
图8 帧同步逻辑流程1
图9 帧同步逻辑流程2
4、最新优化
4.1、断线重连优化
在传统网络模块开发思想中,当发送超时达到阀值,或者底层判定断开连接时,需要重新建立连接。之前这部分工作是交给一个偏上层的模块来执行,该模块需要等Apollo通讯模块连接成功之后,才进行PVP通讯模块的连接。这样使逻辑变得复杂。
由于UDP本身的不可靠性,可以认为网络断线也是其不可靠性的一部分。
而FSP协议栈就是为了解决UDP的不可靠性而设计的,所以也附带解决了断线重连问题。
去除了原来的断线重连逻辑之后,用FSP模块本身的特性来处理断线重连,实测能够提高网络恢复的响应速度。由于PVP服务器设定的超时阀值是15秒,有些时候,其实网络已经恢复,但是由于Apollo通讯模块对网络的恢复响应过于迟钝,造成不必要的判输。
4.2、接入GSDK
从目前接入GSDK后的数据来看,能够减少一定的网络延时,但是并不明显。
4.3、AckOnly优化
AckOnly优化是指减少服务器收到的纯确认包数据。这样做的目的是:
减少包量,有助于在WIFI下节省路由器性能。GSDK有个统计表明,有大概20%多的网络延时是因为路由器性能造成。
节省流量,一定程度上也可以节省网络设备性能,同时在4G下为用户省钱。
该优化分2部分实现:
(1)空帧免确认
(2)WIFI延迟确认
在优化前的AckOnly比例为:57%
空帧免确认优化后降到:38%
WIFI延迟确认优化后降到:25%
5、一些尝试
将FSP模块抽象得与业务无关,使之可快速完成一个使用帧同步方案通讯的Demo成为可能。
实验了本地局域网PVP对局,只要在同一网段下,可以成功对局。(如果有需求,可以实现该功能)
实验了本地蓝牙PVP对局,发现蓝牙是带连接态的,并且其通讯是用类似TCP的数据流进行的。同时它与WIFI信号有干扰,如果开启WIFI,其延时非常高。在非WIFI下,其单条数据的延时很低,但是如果以66MS的频率发送数据,则延时又非常高。
建立了一套用于FSP在线诊断和断线诊断的工具。
本文固定链接:
转载请注明:
文章内容部分来源于互联网,不代表本人的任何立场;本文章涉及到的软件仅供个人下载使用,版权归该软件开发者所有,请支持正版!如果你是原作者,认为本文内容对您的权益有所侵犯,请联系博主进行删除。
由于代码和资料具有可复制性,本站所有代码和资料一经出售,概不退款。买前一定看清楚,支付购买默认就是同意该协议。
感谢您的阅读。喜欢的、有用的就请各位英雄好汉赏几个小钱用于网站的托管!你的物质和精神支持是博主强大的写作动力。欢迎转载!
博主的文章没有高度、深度和广度,只是凑字数。由于博主的水平不高,不足和错误之处在所难免,希望大家能够批评指出。
博主是利用读书、参考、引用、研究、抄袭、复制和粘贴等多种方式打造成自己文章,请原谅博主成为一个无耻的文档搬运工!
作者:Hack_Yin
好记性不如烂笔头,随时记录一些感兴趣的知识或自己跳过的坑,让别人少走一些同样的弯路!
如果您愿意帮助本站一直运行下去,或愿意花几块钱请我喝一杯水的话,请直接向我捐款哦
您可能还会对这些文章感兴趣!
嘿,我是小助手,需要帮助随时点我哦
扫一扫,有惊喜
支付宝微信支付
用户名/邮箱/手机如何快速优化手游性能问题?从UGUI优化说起
WeTest 导读
本文作者从自身多年的Unity项目UI开发及优化的经验出发,从UGUI,CPU,GPU以及unity特有资源等几个维度,介绍了unity手游性能优化的一些方法。
在之前的文章《手游内存占用过高?如何快速定位手游内存问题》中提到,Mono内存和native内存是PSS内存主要的组成部分,mono内存更多的起到内存调用的功能,因此常常成为了开发人员优化内存的起点;而在游戏的其他的进程中,同样有很多因素影响着游戏的性能表现。本文将从UGUI的优化角度,介绍unity游戏性能优化的一些内容。
&
一、UGUI简介
UGUI是Unity官方推出的UI系统,集成了所见即所得的UI解决方案, 其功能丰富并且使用简单,同时其源代码也是开放的,下载地址:
&
相比于NGUI,UGUI有以下几个优点:
1. 所见即所得的编辑方式,在Scene窗口中即可编辑。
2. 智能的Sprite packer可以将图片按tag自动生成图集而无需人工维护,生成的图集合并方式比较合理,无冗余资源。
3. 渲染顺序与GameObject的Hierarchy顺序相关,靠近根节点显示在底层,而靠近叶子节点显示在顶层;这样的渲染方式使得调整UI的层级比较方便和直观。
4. RectTranForm及锚点系统更适合于2D平面布局,并且非常方便多分辨率屏幕自适配。
&
二、UI制作规范和指导方法
本文是关于UGUI优化的,或许你会觉得UI的制作规范及指导方法与优化无关,其实很多性能问题往往是资源的不合理使用造成的,比如使用了尺寸过大的图片、引用了过多的图集以及加载了不必要的资源等。如果从设计和制作UI一开始就遵守特定的规范,则可以规避不必要的性能开销。笔者根据参与的多个项目总结了以下几点通用的规范和指导方法(这些规范适用于所有项目,不管你使用UGUI还是NGUI)。
&
1. 合理的分配图集
合理的分配图集可以降低drawcall和资源加载速度;具体细节如下:
● 同一个UI界面的图片尽可能放到一个图集中,这样可以尽可能的降低drawcall。
&
● 共用的图片放到一个或几共享的图集中,例如通用的弹框和按钮等;相同功能的图片放到一个图集中, 例如装备图标和英雄头像等;这样可以降低切换界面的加载速度。
&
● 不同格式的图片分别放到不同的图集中,例如透明(带Alpha)和不透明(不带Alpha)的图片,这样可以减少图片的存储空间和占用内存。(UGUI的sprite packer会自动处理这种情况)
&
2. resources目录中应该只保存prefab文件,其它非prefab文件(例如动画,贴图,材质等)应放到resource目录之外
因为随着项目的迭代,可能会导致部分资源(动画,贴图)等失效,如果这些文件放在resource目录下,在打包时,unity会将resource目录下文本全部打成一个大的AssetBundle包(非resouce目录下的文件只有在引用到时才会被打到包里),从而出现冗余,增加不必要的存储空间和内存占用。可以通过以下代码(Mac环境下)在控制台窗口中查看当前目录下所有非prefab资源的代码:
find . -type f | egrep -v &(prefab|prefab\.meta|meta)$&
&
例如在笔者的一次扫描中,发现在了如下结果:
&
3. 关卡内的UI资源不要与外围系统UI资源混用
在关卡内,需要加载大量的角色及场景资源,内存比较吃紧,一般在进入关卡时,都会手动释放外围系统的资源,以便使关卡内有更多的内存可以使用。如果战斗内的UI与外围系统的UI使用相同图集里的图片,则有可能会使得外围系统的图片资源释放不成功。对于关卡内与外围共用的UI资源需要特殊处理,一般来说复制一份出来专门给关卡内使用是比较好的选择。
&
4. 适当的降低图片的尺寸
有时UI系统的背景可能会使用全屏大小的图片,比如在Iphone上使用大小的图片;使用这样尺寸的图片代价是很昂贵的,可以和美术同学商量适当的降低图片的精度,使用更低尺寸的图片。
&
5. 在android设备上使用etc格式的图片
目前,几乎所有android设备都支持etc1格式的图片,etc1的好处是第个像素点只战用0.5个字节而普通rgba32的图片每个像素点占4个字节,也就说一张图片如果使用rgba32的格式所占用的内存为4M而etc1格式所占用的内存仅为0.5M。但是使用etc1格式的图片有两个限制——长和宽必须是POT的(2的N次方)并且不支持alpha通道,因此使用etc1时需要额外的一张图来存储alpha通道,并且使用特殊的shader来对alpha采样。具体的细节可参考:
&
6. 删除不必要的UI节点、动画组件及资源
随着项目的迭代,可能有部分ui节点及动画已经失效,对于失效的节点及动画一定要删除,在很多项目中,有部分同学为了方便省事,只是将失效的节点及动画disable了。这样做虽然在运行时不会对cpu造成太多负担,但是在加载时会增加不必要的加载时间以及内存占用。对于废弃的UI图片资源,虽然未放到Resource目录最终不会打到包里,但是在Editor模式下仍然会打到图集中从而影响优化决策。笔者写了一个扫描未使用到UI贴图资源的工具,代码地址:;
&
另外,对于废弃的脚本,可能还会有某些对象持有对它的引用,而加载这样的对象也比较耗时,笔者也写了一个扫描废弃脚本的工具,代码地址:
&
三、CPU优化
一般来说,优化cpu性能应该先用profiler定位到性能热点,找到消耗最高的函数,然后再想办法降低它的消耗。经过笔者多次使用profiler对UGUI的分析来看,其CPU性能开销高主要原因之一是Canvs对UI网格的重建,有很多情况会触发Canvas对网格的重建,例如Image,Text等UI元素的Enable及UI元素的长、宽或Color属性的变化等。Canvas中UI Mesh顶点较多的话,则该项将会出现较高的CPU开销。在Unity的Profiler中则对应的是Canvas.SendWillRenderCanvases或Canvas.BuildBatch占用过多的时间。
&
Canvas.BuildBatch主要功能是合并Canvas节点下所有UI元素的网格,合并后的网格会缓存起来,只有其下面的UI元素的网格发生改变时才会重新合并。而UI元素的网络变化主要是因为Canvas.SendWillRenderCanvases调用时,rebuild了Layout或者craphic。该函数的调用过程时序图如下: 726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" title="点击查看原图" onclick="if(this.parentNode.tagName!='A') window.open('http://www.ceeger.com/forum/attachment/1612/thread/27_eec903e1758ab.png');" />
&
1.该过程由CanvasUpdateRegistry监听Canvas的WillRenderCanvases(上图中1)而执行,主要是对前标记为dirty的layout和craphic执行rebuild。引起layout和graphic的dirty主要原因是因为Canvas树形结构下的UI元素发生了变化(例如增加删除UI对象,UI元素的顶点,rec尺寸改变等)调用了Graphic.SetDirty(实际上最终都会调用CanvasUpdateRegistry.RegisterCanvasElementForLayoutRebuild)。
&
2. 在rebuild layout之前会对Layout rebuild queue中的元素依据它们在heiarchy中的层次深度进行排序(上图中的2),排列的结果是越靠近根的节点越会被优先处理。
&
3. rebuild layout(上图中的3),主要是执行ILayoutElement和ILayoutController接口中的方法来计算位置,Rect的大小等布局信息。
&
4. rebulid graphic(上图中的4),主要是调用UpdateGeometry重建网格的顶点数据(上图中5)以及调用UpdateMeterial更新CanvasRender的材质信息(上图中6)。
&
基于以上UGUI的网格更新原理,我们可以做以下优化:
a. 使用尽可能少的UI元素;在制作UI时,一定要仔细查检UI层级,删除不不必要的UI元素,这样可以减少深度排序的时间(上图中的2)以及Rebuild的时间(上图中的3,4)。
&
b. 减少Rebuild的频率,将动态UI元素(频繁改变例如顶点、alpha、坐标和大小等的元素)与静态UI元素分离出来,放到特定的Canvas中。
&
c. 谨慎使用UI元素的enable与disable,因为它们会触发耗时较高的rebuild(图中的3、4),替代方案之一是enable和disableUI元素的canvasrender或者Canvas。
&
d. 谨慎使用Text的Best Fit选项,虽然这个选项可以动态的调整字体大小以适应UI布局而不会超框,但其代价是很高的,Unity会为用到的该元素所用到的所有字号生成图元保存在atlas里,不但增加额外的生成时间,还会使得字体对应的atlas变大。 726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" title="点击查看原图" onclick="if(this.parentNode.tagName!='A') window.open('http://www.ceeger.com/forum/attachment/1612/thread/27_6e8a2394f22a.png');" />
&
&
e.谨慎使用Canvas的Pixel Perfect选项,该选项会使得ui元素在发生位置变化时,造成layout Rebuild。(比如ScrollRect滚动时,如果开启了Canvas的pixel Perfect,会使得Canvas.SendWillRenderCanvas消耗较高) 726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" title="点击查看原图" onclick="if(this.parentNode.tagName!='A') window.open('http://www.ceeger.com/forum/attachment/1612/thread/27_edfaa61b451e4.png');" />
&
f. 使用缓存池来保存ScrollView中的Item,对于移出或移进View外的的元素,不要调用disable或enable,而是把它们放到缓存池里或从缓存池中取出复用。
&
g. 除了rebuild过程之外,UGUI的touch处理消耗也可能会成为性能热点。因为UGUI在默认情况下会对所有可见的Graphic组件调用raycast。对于不需要接收touch事件的grahic,一定要禁用raycast。对于unity5以上的可以关闭graphic的Raycast Target而对于unity4.6,可以给不需要接收touch的UI元素加上canvasgroup组件。
&
unity5.x
726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" title="点击查看原图" onclick="if(this.parentNode.tagName!='A') window.open('http://www.ceeger.com/forum/attachment/1612/thread/27_2d0e7cef8d50.png');" />
&
unity4.6 726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" title="点击查看原图" onclick="if(this.parentNode.tagName!='A') window.open('http://www.ceeger.com/forum/attachment/1612/thread/27_b.png');" />726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" title="点击查看原图" onclick="if(this.parentNode.tagName!='A') window.open('http://www.ceeger.com/forum/attachment/1612/thread/27_f76bdcaea9b151.png');" />
&
&
四、GPU优化
一般来说,造成GPU性能瓶颈主要有两个原因:复杂的vertext或pixel shader计算以及overdraw造成过多的像素填充。在默认情况下UGUI中所有UI元素使用都使用UI/Defaut shader,因此在优化时可优先考虑解决Overdraw问题。Overdraw主要是因为大量UI元素的重叠引起的,查看overdraw比较简单,在scene窗口中选择overdraw模式,场景中越亮的地方表示overdraw越高(如下图)。 726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" title="点击查看原图" onclick="if(this.parentNode.tagName!='A') window.open('http://www.ceeger.com/forum/attachment/1612/thread/27_6da66498a53e.png');" />
为了降低overdraw,可以做如下优化:
1. 禁用不可见的UI,比如当打开一个系统时如果完全挡住了另外一个系统,则可以将被遮挡住的系统禁用。
2. 不要使用空的Image,在Unity中,RayCast使用Graphi作为基本元素来检测touch,在笔者参与的项目中,很多同学使用空的image并将alpha设置为0来接收touch事件,这样会产生不必要的overdraw。通过如下类NoDrawingRayCast来接收事件可以避免不必要的overdraw。
3. public class NoDrawingRayCast : Graphic
4. {
5. & & public override void SetMaterialDirty()
6. & & {
7. & & }
8. & & public override void SetVerticesDirty()
9. & & {
10. & & }
11. & & protected override void OnFillVBO(List&UIVertex& vbo)
12. & & {
13. & & & & vbo.Clear();
14. & & }
}
&
五、总结
优化UGUI性能没有万能的方法,笔者这些经验总结也只能作为参考。优化性能往往是在各种选择之间做出平衡,比如drawcall与rebuild平衡、内存战胜与cpu消耗平衡以及UI图片精度与纹理大小的平衡等。每一次优化都有可能使得瓶颈出现在其它的环节上,要善于使用profiler,找到性能热点,对症下药。
&
六、关于资源占用问题
UI资源优化是UGUI性能优化的重点,腾讯WeTest也在资源方面提供了性能的测试。以下通过“纹理”资源,介绍腾讯WeTest性能测试在资源方面的测试情况。
1、登录 ,点击“Android版 下载”,或者在页面末尾扫描二维码直接下载腾讯WeTest的手游客户端性能分析工具Cube。打开工具,选择“Unity资源分析”。
2、上传测试报告后,我们可以通过测试报告,了解unity游戏的资源情况。
&
&
资源结论概况
进入资源数据的报告之后,首先可以看到所有资源数据的概况结果,总体上了解存在问题的数据,继续下拉,可以了解该指标的具体情况。 726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" title="点击查看原图" onclick="if(this.parentNode.tagName!='A') window.open('http://www.ceeger.com/forum/attachment/1612/thread/27_e0e1ac820bdef.png');" />资源数据概况
&
下面将以“纹理资源”为例,对cube资源测试报告进行解读。
&
纹理资源
Cube测试报告的“纹理资源”,根据腾讯标准,是期望&50MB的,从下图可见,如果超出红色虚线,就说明纹理资源存在超标。 726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" title="点击查看原图" onclick="if(this.parentNode.tagName!='A') window.open('http://www.ceeger.com/forum/attachment/1612/thread/27_f4cd7e0d23168.png');" />点击具体数据点,获取具体资源数据
&
另外,点击图表中的绿色线条中的具体数据点,可以看到这个点的当前数据,所有数据根据资源大小进行排序726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" title="点击查看原图" onclick="if(this.parentNode.tagName!='A') window.open('http://www.ceeger.com/forum/attachment/1612/thread/27_574fa3027e9f.png');" /> 所有数据根据资源大小进行排序
&
在这个表之下,有一个“资源大小top20”的表格,罗列了资源排名前20的资源内容。其中资源大小超过建议值的会呈现红色,资源大小非2的n次幂的呈现黄色。点击任意一个资源名称,可以在图表上观察这个资源所影响的区域:726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" title="点击查看原图" onclick="if(this.parentNode.tagName!='A') window.open('http://www.ceeger.com/forum/attachment/1612/thread/27_bf5a9d3fbf449.png');" /> 点击具体资源了解影响区域
726 || this.offsetHeight>700){if(this.offsetWidth/726 > this.offsetHeight/700){this.width=726;}else{this.height=700;}}" style="max-width:726max-height:700" title="点击查看原图" onclick="if(this.parentNode.tagName!='A') window.open('http://www.ceeger.com/forum/attachment/1612/thread/27_5.png');" />了解资源调用的影响区域
&针对手游的性能优化,腾讯WeTest平台的Cube工具提供了基本所有相关指标的检测,为手游进行最高效和准确的测试服务,不断改善玩家的体验。目前功能还在免费开放中。
&
体验地址:
帮助中心:
如果对使用当中有任何疑问,欢迎联系腾讯WeTest企业qq:
要评论请先&或者&
萌新表示虽然看不太懂,不过应该很有用先存着
多谢分享,好有深度的文章
好文章啊,我已找了很久了。。。

我要回帖

更多关于 where 1 1 消耗性能吗 的文章

 

随机推荐