建议读者先看这篇博文:http://blog.csdn.net/zzxiang1985/article/details/43339273,有些技术已经变了,比如第1招,unity5的打包机制已经变许多了。不像其他招基本还是可以学习的,比如:透明通道分离,关闭texture read/write选项(其实其他资源得read/write选项也类似,比如动画资源等),减少场景中的GameObject数量,整理图集(一般是一个面板使用2个图集:当前面板一个图集+基本图集),使用多个UIPanel隔开dc避免一个dc改变却重绘大量dc等。

  一、下面是我主要针对减少ngui的dc做法进行补充:

    第一,我们需要知道ngui的dc是UIPanel隔开的,每个uipanel管理自己的dc;

    第二,对于一个uipanel,每个dc有自己的uiwidgets列表,有自己的纹理/材质,和uipanel分配的深度depth范围,dc合批的情况:纹理一样,材质一样,并且2者的深度范围是相邻的,就会合批。合批之后,新dc的深度范围包含2个dc范围(其实看过源码的都知道这种说法是不对的,正确的是,每加入一个uiwidget,uipanel会根据它的纹理材质深度给它找一个现有dc:纹理一样,材质一样,并且2者的深度范围是相邻的,找不到就新建一个dc给它);

    第三,dc的重构:包括2种:uipanel.FillDrawCall和uipanel.FillAllDrawCalls,顾名思义,前者是给某个dc重绘,后者是给该uipanel所有dc重绘,这在文首那篇博文提到了。

      第一种重构是当某个dc.isDirty时重绘:这里只谈非手动重绘且是运行过程中重绘的情况:

       1.dc的uiwidgets中有顶点变化,顶点位置变化或者有widget透明度变化(一个widget的透明度由整个widget的垂直结构决定,自己的*父亲的*父亲的父亲的...)

       2.removewidget时,所以尽量不要运行时removewidget

       3.addwidget时

      第二种重构是当uipanel.mRebuild=true时重绘:这里只谈非手动重绘且是运行过程中重绘的情况:

       1.addwidget时,如果找不到现有的dc给它使用,mRebuild=true,

       2.removewidget时,如果该widget的有dc且该dc的深度是uipanel中所有dc深度的最小或最大深度时,mRebuild=true

   总结:

    对于第一,uipanel很少时,dc之间会影响很大,要是某个dc经常导致FillAllDrawCalls,那就大家一起遭殃,但如果uipanel很多,本身就增加了很多dc,因为uipanel之间的dc是独立的,不能合批的,所以项目中也不要滥用uipanel;

    对于第二第三,实际应用时,一般把跳字,血条等经常重绘的的ui分出去作为一个uipanel,主面板的uipanel可以这样分割成:staticpanel,movepanel1,movepanel2...,并且可以看到remove和add widget对重绘影响很大,所以尽量不要运行时干这两件事,除非你知道会发生什么。

    此外,对于一个系统的面板,一般使用自己的图集和公共图集,这个时候要特别注意尽量合批dc,避免各个不同图集uiwidget的depth交叉导致相同图集widget的dc不能合批,我在制作UI面板时一般<1的深度给背景图,1-9给公共图集,10-20给该系统的图集,50-60给公共图集,这样就基本做到:能合批的都能合批,实际工作上要养成点击uipanel的showdrawcall,打开dc显示面板,查看是否分割的太厉害或者能否合批,的习惯。

 二、对UIScrollView的优化:如果大量GameObject挂到Scrollview下面的话,会导致卡顿,可以通过设置不显示的gameobj为false来减少卡顿。

 三、用List<int>和Dictionary<int,xx>代替List<enum>和Dictionary<enum>,因为后者在各种操作中经常调用其equal函数: 

    比如List<T>的equal会调用T的default EqualityComparer,而The default EqualityComparer for enums uses the Enum.Equals method:
    public override bool Equals(object obj)=》有装箱拆箱操作,增加了gc(Dictionary类似)

 四、用for代替foreach遍历list,用var iter=dic.getenumtor(); while(iter.movenext()){}iter.dispose();遍历dic,这个是unity自带mono的bug,会多装箱拆箱操作导致gc。读者先检测自己的Unity版本是否修复了此bug,如果修复了则忽略此条。

 五、lamda表达式会导致gc,原因是每次调用lamda表达式时new出了一个托管对象,所以如果lamda内部函数不需要使用外部函数的数据变量,那就不要使用lamda。

Unity NGUI C#性能优化的更多相关文章

  1. Unity性能优化的N种武器

    贴图: l  控制贴图大小,尽量不要超过 1024 x1024: l  尽量使用2的n次幂大小的贴图,否则GfxDriver里会有2份贴图: l  尽量使用压缩格式减小贴图大小: l  若干种贴图合并 ...

  2. Unity技术支持团队性能优化经验分享

    https://mp.weixin.qq.com/s?__biz=MzU5MjQ1NTEwOA==&mid=2247490321&idx=1&sn=f9f34407ee5c5d ...

  3. 用好lua+unity,让性能飞起来——lua与c#交互篇

    前言 在看了uwa之前发布的<Unity项目常见Lua解决方案性能比较>,决定动手写一篇关于lua+unity方案的性能优化文. 整合lua是目前最强大的unity热更新方案,毕竟这是唯一 ...

  4. Unity 性能优化(力荐)

    开始之前先分享几款性能优化的插件: 1.SimpleLOD : 除了同样拥有Mesh Baker所具有的Mesh合并.Atlas烘焙等功能,它还能提供Mesh的简化,并对动态蒙皮网格进行了很好的支持. ...

  5. Unity性能优化(3)-官方教程Optimizing garbage collection in Unity games翻译

    本文是Unity官方教程,性能优化系列的第三篇<Optimizing garbage collection in Unity games>的翻译. 相关文章: Unity性能优化(1)-官 ...

  6. Unity性能优化(4)-官方教程Optimizing graphics rendering in Unity games翻译

    本文是Unity官方教程,性能优化系列的第四篇<Optimizing graphics rendering in Unity games>的翻译. 相关文章: Unity性能优化(1)-官 ...

  7. Unity性能优化(2)-官方教程Diagnosing performance problems using the Profiler window翻译

    本文是Unity官方教程,性能优化系列的第二篇<Diagnosing performance problems using the Profiler window>的简单翻译. 相关文章: ...

  8. Unity性能优化(1)-官方教程The Profiler window翻译

    本文是Unity官方教程,性能优化系列的第一篇<The Profiler window>的简单翻译. 相关文章: Unity性能优化(1)-官方教程The Profiler window翻 ...

  9. [Unity优化] Unity CPU性能优化

    前段时间本人转战unity手游,由于作者(Chwen)之前参与端游开发,有些端游的经验可以直接移植到手游,比如项目框架架构.代码设计.部分性能分析,而对于移动终端而言,CPU.内存.显卡甚至电池等硬件 ...

随机推荐

  1. 关于innerHtml= 与 html() 区别

    今天遇到的问题:如果写入的html 有<script>,必须用JQuery 的 html() 才能识别: 使用innerHtml 无法识别<script> 原因机制:待查询

  2. 【Python】利用递归函数调用方式,将所输入的字符串,以相反的顺序显示出来

    源代码: """ 利用递归函数调用方式,将所输入的字符串,以相反的顺序显示出来 string_reverse_output():反向输出字符串的自定义函数 pending ...

  3. R入门-图表

    画直方图:hist(x$x1)  //参数为向量,x为表图 画散点图:plot(x1,x2) // plot(x$x1,x$x2) // 列联表分析: 列联函数table() // table(x$x ...

  4. C、C++、boost、Qt在嵌入式系统开发中的使用

    概述 嵌入式系统开发相对来说属于偏底层的开发,也就是与硬件结合比较紧密,只能使用C/C++语言.对于做平台开发的人来说,C语言真的是很"古老"的语言,属于操作系统语言!好多人会觉得 ...

  5. PHP7 生产环境队列 Beanstalkd 正确使用姿势

    应用场景 为什么要用呢,有什么好处?这应该放在最开头说,一件东西你只有了解它是干什么的,适合干什么,才能更好的与自己的项目相结合,用到哪里学到哪里,学了不用等于不会,我们平时就应该多考虑一些这样的问题 ...

  6. javascript对象笔记

    JS对象     对象是一个具体的事物     在JS中对象是一组无序属性和方法的集合例如字符串,数组,函数等等     对象是由属性和方法组成的     属性:是事物的特征,在对象中用属性来表示一般 ...

  7. C#LeetCode刷题-几何

    几何篇 # 题名 刷题 通过率 难度 587 安装栅栏   21.5% 困难 892 三维形体的表面积 C#LeetCode刷题之#892-三维形体的表面积(Surface Area of 3D Sh ...

  8. Golang gRPC学习(03): grpc官方示例程序route_guide简析

    代码主要来源于grpc的官方examples代码: route_guide https://github.com/grpc/grpc-go/tree/master/examples/route_gui ...

  9. 重回OI的第一篇博客

    太久没学OI了, 代码都不会写了, 先写一篇BFS练练手, 是我太菜了qwq #include<cstdio> #include<queue> #include<iost ...

  10. (转)C# 获取当前路径的7中方法

    //获取模块的完整路径. string path1 = System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName; //获取 ...