位置: 编程技术 - 正文

Unity+NGUI性能优化方法总结(unity outline性能)

编辑:rootadmin

推荐整理分享Unity+NGUI性能优化方法总结(unity outline性能),希望有所帮助,仅作参考,欢迎阅读内容。

文章相关热门搜索词:unity性能优化总结,unity性能优化总结,unity性能和内存优化,unity性能怎么样,unity性能怎么样,unity性能怎么样,unity性能怎么样,unity性能怎么样,内容如对您有帮助,希望把文章链接给更多的朋友!

一共9招。

1 资源分离打包与加载

  游戏中会有很多地方使用同一份资源。比如,有些界面会共用同一份字体、同一张图集,有些场景会共用同一张贴图,有些会怪物使用同一个Animator,等等。可以在制作游戏安装包时将这些公用资源从其它资源中分离出来,单独打包。比如若资源A和B都引用了资源C,则将C分离出来单独打一个bundle。在游戏运行时,如果要加载A,则先加载C;之后如果要加载B,因为C的实例已经在内存,所以只要直接加载B,让B指向C即可。如果打包时不将C从A和B分离出来,那么A的包里会有一份C,B的包里也会有一份C,冗余的C会将安装包撑大;并且在运行时,如果A和B都加载进内存,内存里就会有两个C实例,增大了内存占用。

  资源分离打包与加载是最有效的减小安装包体积与运行时内存占用的手段。一般打包粒度越细,这两个指标就越小;而且当两个renderQueue相邻的DrawCall使用了相同的贴图、材质和shader实例时,这两个DrawCall就可以合并。但打包粒度也并不是越细就越好。如果运行时要同时加载大量小bundle,那么加载速度将会非常慢——时间都浪费在协程之间的调度和多批次的小I/O上了;而且DrawCall合并不见得会提高性能,有时反而会降低性能,后文会提到。因此需要有策略地控制打包粒度。一般只分离字体和贴图这种体积较大的公用资源。

  可以用AssetDatabase.GetDependencies得知一份资源使用了哪些其它资源。

2 贴图透明通道分离,压缩&#;式设为ETC/PVRTC

  最初我们使用了DXT5作为贴图压缩&#;式,希望能减小贴图的内存占用,但很快发现移动平台的显卡是不支持硬件解压DXT5的。因此对于一张x大小的RGBA贴图,虽然DXT5可将它从4MB压缩到1MB,但系统将它送进显卡之前,会先用CPU在内存里将它解压成4MB的RGBA&#;式(软件解压),然后再将这4MB送进显存。于是在这段时间里,这张贴图就占用了5MB内存和4MB显存;而移动平台往往没有独立显存,需要从内存里抠一块作为显存,于是原以为只占1MB内存的贴图实际却占了9MB!

  所有不支持硬件解压的压缩&#;式都有这个问题。经过一番调研,我们发现安卓上硬件支持最广泛的&#;式是ETC,苹果上则是PVRTC。但这两种&#;式都是不带透明(Alpha)通道的。因此我们将每张原始贴图的透明通道都分离了出来,写进另一张贴图的红色通道里。这两张贴图都采用ETC/PVRTC压缩。渲染的时候,将两张贴图都送进显存。同时我们修改了NGUI的shader,在渲染时将第二张贴图的红色通道写到第一张贴图的透明通道里,恢复原来的颜色:

[plain] view plaincopyfixed4 frag (v2f i) : COLOR { fixed4 col; col.rgb = tex2D(_MainTex, i.texcoord).rgb; col.a = tex2D(_AlphaTex, i.texcoord).r; return col * i.color; }

  这样,一张4MB的x大小的RGBA原始贴图,会被分离并压缩成两张0.5MB的ETC/PVRTC贴图(我们用的是ETC/PVRTC 4 bits)。它们渲染时的内存占用则是2x0.5&#;2x0.5=2MB。

3 关闭贴图的读写选项

  Unity中导入的每张贴图都有一个启用可读可写(Read/Write Enabled)的开关,对应的程序参数是TextureImporter.isReadable。选中贴图后可在Import Setting选项卡中看到这个开关。只有打开这个开关,才可以对贴图使用Texture2D.GetPixel,读取或改写贴图资源的像素,但这就需要系统在内存里保留一份贴图的拷贝,以供CPU访问。一般游戏运行时不会有这样的需求,因此我们对所有贴图都关闭了这个开关,只在编辑中做贴图导入后处理(比如对原始贴图分离透明通道)时打开它。这样,上文提到的x大小的贴图,其运行时的2MB内存占用又可以少一半,减小到1MB。

4 减少场景中的GameObject数量

  有一次我们将场景中的GameObject数量减少了近2万个,游戏在iPhone 3S上的内存占用立马减了MB。这些GameObject虽然基本是在隐藏状态(activeInHierarchy为false),但仍然会占用不少内存。这些GameObject身上还挂载了不少脚本,每个GameObject中的每个脚本都要实例化,又是一比不菲的内存占用。因此后来我们规定场景中的GameObject数量不得超过1万,并且将GameObject数量列为每周版本的性能监测指标。

5 整理图集

  整理图集的主要目的是节省运行时内存(虽然有时也能起到合并DrawCall的作用)。从这个角度讲,显示一个界面时送进显存的图集尺寸之和是越小越好。一般有如下方法可以帮助我们做到这点:

  1)在界面设计上,尽量让美术将控件设计为可以做九宫&#;拉伸,即UISprite的类型为Sliced。这样美术就可以只切出一张小图,我们在Unity中将它拉大。当然,一个控件做九宫&#;也就意味着其顶点数量从4个增加到至少个(九宫&#;的中心&#;子采用Tiled做平铺类型的话,顶点数会更多),构建DrawCall的开销会更大(见第6点),但一般只要DrawCall安排合理(同样见第6点)就不会有问题。

  2)同样是在界面设计上,尽量让美术将图案设计成对称的形式。这样切图的时候,美术就可以只切一部分,我们在Unity中将完整的图案拼出来。比如对一个圆形图案,美术可以只切出四分之一;对一张脸,美术可以只切出一半。不过,与第1)点类&#;,这个方法同样有其它性能代价——一个图案所对应的顶点数和GameObject数量都增多了。第4点已经提到,GameObject数量的增多有时也会显著占用更多内存。因此一般只对尺寸较大的图案采用这个方法。

  3)确保不要让不必要的贴图素材驻留内存,更不要在渲染时将无关的贴图素材送进显存。为此需要将图集按照界面分开,一般一张图集只放一个界面的素材,一个界面中的UISprite也不要使用别的界面的图集。假设界面A和界面B上都有一个小小的一模一样的金币图标,不要因为在制作时贪图方便,就让界面A的UISprite直接引用界面B中的金币素材;否则界面A显示的时候,会将整个界面B的图集也送进显存,而且只要A还在内存中,B的图集也会驻留内存。对于这种情况,应该在A和B的图集中各放一个一模一样的金币图标,A中的UISprite只使用A的图集,B中的UISprite只使用B的图集。

Unity+NGUI性能优化方法总结(unity outline性能)

  不过,如果两个界面之间存在大量相同的素材,那么这两个界面就可以共用同一张图集。这样可以减少所有界面的总内存占用量。具体操作时需要根据美术的设计进行权衡。一般界面之间相同的通用的素材越多,程序的内存负担就越小。但界面之间相同的东西太多的话,美术效果可能就不生动,这是美术和程序之间又一个需要寻求平衡的地方。

  另外,数量庞大的图标资源(如物品图标)不要做在图集里,而应该采用UITexture。

  4)减少图集中的空白地方。图集中完全透明的像素和不透名的像素所占的内存空间其实是一样的。因此在素材量不变的情况下,要尽量减少图集中的空白。有时一张x的图集中,素材所占的面积还没超过一半,这时可以考虑将这张图集切成两张x的图集。(可能有人会问为什么不能做成一张x的图集,这是因为iOS平台&#;乎要求送进显存的贴图一定是方形。)当然,两张不同图集的DrawCall是无法合并的,但这并不是什么问题(见第6点)。

  应该说,图集的整理在具体操作时并没有一成不变的标准,很多时候需要权衡利弊来最终决定如何整理,因为不管哪种措施都会有别的性能代价。

6 根据各个UI控件的设计安放Panel,隔开DrawCall

  有一次我们发现NGUI的UIPanel.LateUpdate函数的CPU开销非常大。仔细研究之后,发现是合并了太多的DrawCall所致,尤其是将运行时会运动变化的UI控件和静止不变的UI控件的DrawCall合在了一起。当一个UI控件(UIWidget)的位置、大小或颜色等属性发生变化时,UIPanel就需要重建这个控件所用的DrawCall,某些情况下还要重建Panel上的所有DrawCall。有时重建一个DrawCall会消耗不少CPU开销,它需要重新计算这个DrawCall上所有控件的顶点信息,包括顶点位置、UV和颜色等。如果很多控件都集中在同一个DrawCall上,那么只要一个控件有一点点变化,这个DrawCall上的所有控件的顶点就都要重新遍历一边;而我们的UI又大量采用了九宫&#;拉伸,使控件的顶点数量变得更多,因此重建一个DrawCall的开销就更大。

  因此我们将UI控件分组,将一段时间内会发生变化的控件——比如怪物头顶的血条和伤害跳字放在同一个Panel上,并且这个Panel上只有这些控件,其余基本不变化的控件就放在别的Panel上。这样两类控件就被隔开到不同的DrawCall不同的Panel中,当一个控件发生变化而导致DrawCall重建时,就不需要遍历那些没有变化的控件。因为在美术设计上,一段时间内在变化的控件总是少数,所以优化效果十分明显,节省的CPU占用率能达到%。

  这种方法会增加一些DrawCall,但不会有什么影响。我们项目中前期曾经过于重视DrawCall数量的压缩,但后来发现增加几个DrawCall并不是那么可怕的事情。主程有一次甚至用Cocos2d-x做过试验,即使在个DrawCall的情况下,动画依然可以跑得很流畅,相比之下贴图大小对流畅度的影响要大得多。

7 优化锚点内部逻辑,使其只在必要时更新

  在上一点优化了Panel的DrawCall重建效率之后,我们发现NGUI锚点自身的更新逻辑也会消耗不少CPU开销。即使是在控件静止不动的情况下,控件的锚点也会每帧更新(见UIWidget.OnUpdate函数),而且它的更新是递归式的,使CPU占用率更高。因此我们修改了NGUI的内部代码,使锚点只在必要时更新。一般只在控件初始化和屏幕大小发生变化时更新即可。不过这个优化的代价是控件的顶点位置发生变化的时候(比如控件在运动,或控件大小改变等),上层逻辑需要自己负责更新锚点。

8 降低贴图素材分辨率

  这一招说白了其实就是减小贴图素材的尺寸。比如对一张在原画里尺寸是x的贴图,我们将它导入Unity后会把它缩小到x,即缩小两倍。游戏实际使用的是缩小后的贴图。不过这一招是必然会显著降低美术品质的,美术立马会发现画面变得更模糊,因此一般不到程序撑不住的时候不会采用。

9 界面的延迟加载和定时卸载策略(暂未实施)

  如果一些界面的重要性较低,并且不常被使用,可以等到界面需要打开显示的时候才从bundle加载资源,并且在关闭时将自己卸载出内存,或者等过一段时间再卸载。不过这个方法有两个代价:一是会影响体验,玩家要求打开界面时,界面的显示会有延迟;二是更容易出bug,上层写逻辑时要考虑异步情况,当程序员要访问一个界面时,这个界面未必会在内存里。因此目前为止我们仍未实施该方案。目前只是进入一个新场景时,卸载上一个场景用到但新场景不会用到的界面。

  以上的9个方法中,4、5、6需要在一定程度上从策划和美术的角度考虑问题,并且需要持续保持监控以维护优化状态(因为在设计上总是会有新界面的需求或改动老界面的需求);其它都是一劳永逸的解决方案,只要实施稳定后,就不需要再在上面花费精力。不过2和8都是会降低美术品质的方法,尤其是8。如果美术对品质的降低程度实在忍不了的话,也可能不会允许采用这两个方法。

后记

后来又学到一招:

避免频繁调用GameObject.SetActive

原文地址

[Unity3D]Stencil buffer失效了怎么办 摘要在unity4.6.5f1这个版本中,shader中使用stencilbuffer时候,出现了stencil无效的情况,怎么办。正文在unity4.6.5f1这个版本中,shader中使用stencilbuffer时候,

事件/委托机制(event/delegate)(Unity3D开发之十七) 猴子原创,欢迎转载。转载请注明:转载自Cocos2Der-CSDN,谢谢!原文地址:

[置顶] Unity3D实现弹幕的效果 孙广东.6.对于逗比的游戏、无厘头、可以让大家吐糟的游戏,如果有弹幕的功能是极好的。使用U5和UGUI目前实现的很简陋而已。///summary///实现看视

标签: unity outline性能

本文链接地址:https://www.jiuchutong.com/biancheng/369253.html 转载请保留说明!

上一篇:当摄像机被墙挡住后,墙消失,相反则出现(三维坐标到二维坐标的转换实例Camera.main.WorldToScreenPoint)(摄像头挡住了)

下一篇:[Unity3D]Stencil buffer失效了怎么办

  • 外籍人员个人所得税政策2022
  • 生产设备保险费会计分录
  • 工商年报纳税总额怎么算
  • 异地预缴怎么做账
  • 金融企业逾期贷款税前扣除
  • 企业筹建期间开办费计入什么科目
  • 税务登记后怎么领发票
  • 发票过期了还能抵扣吗
  • 长期股权投资属于金融资产吗
  • 项目清算组
  • 固定资产附加的账务处理
  • 经销商注册什么公司
  • 个体工商户怎么分配股份
  • 营改增施工企业哪些能退
  • 企业电话费计入什么科目
  • 公司不收员工的个人所得税怎么处理?
  • 贸易公司一般纳税多少
  • 合同中补充协议
  • 什么凭证需要审计报告
  • 服务性行业受气
  • 委托出口业务的账务如何处理呢?
  • 企业收到红字发票,应该如何申报报表?
  • 因税负低补缴上年度增值税分录怎么写?
  • 主营业务收入写不写明细
  • 个人业务费是什么
  • 已认证抵扣的进项税额转出做账的会计处理
  • 什么是商务接待与拜访
  • cmos bjt
  • 如何禁止远程
  • 购买交易性金融资产时,支付的交易费用应计入
  • php.ini配置文件
  • vim diff对比
  • php定义的异常
  • 黑枣的功效与作用图片
  • 最早的拍照手机是哪一年
  • 进货退回的会计处理
  • Escarpment Trail in Porcupine Mountains Wilderness State Park, Michigan (© Pat & Chuck Blackley/Alamy)
  • 计算完工产品成本
  • 在产品按定额成本计价法的特点
  • 固定资产与固定资产净值
  • 准备动作怎么做
  • 微前端Qiankun 子应用css后加载问题
  • 银行询证函费用减免
  • php备份mysql数据库
  • 酒店押金的账务处理
  • 什么是应收账款信用管理制度
  • 织梦如何添加浮动广告
  • mysql中文乱码怎样用代码解决
  • 织梦cms要钱吗
  • 捐款怎么组织
  • 生产成本中制造费用中包括哪些?
  • 公司向员工发放的慰问金怎么做账
  • 营改增之后账务怎么处理
  • 利得和损失计入所有者权益的情况
  • 收客户货款怎么说话
  • 小规模纳税人怎么申报个人所得税
  • 营业成本占营业收入的比重过高
  • 客户将发票丢了怎么赔偿
  • 营改增后建筑业税率
  • 农村会计记账实例
  • Mysql version can not be less than 4.1 出错解决办法
  • mysql事务命令
  • mac查找序列号
  • linux 解析
  • 桌面快捷方式不显示图标怎么办
  • 通用pe工具箱安装win7
  • window英语
  • Win10桌面图标怎么隐藏
  • linux使用范围
  • winfs.exe - winfs是什么进程
  • 删除xp本地保存的视频
  • mac如何搜索应用
  • win1021年更新
  • vps如何搭建ss
  • window10添加虚拟网卡
  • 将txt文件名批量导入excel
  • node.js + socket.io 实现点对点随机匹配聊天
  • JavaScript焦点事件、鼠标事件和滚轮事件使用详解
  • 怎么向税局举报
  • 出口退税函调不予退税的后果
  • 免责声明:网站部分图片文字素材来源于网络,如有侵权,请及时告知,我们会第一时间删除,谢谢! 邮箱:opceo@qq.com

    鄂ICP备2023003026号

    网站地图: 企业信息 工商信息 财税知识 网络常识 编程技术

    友情链接: 武汉网站建设