建议读者先看这篇博文: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. 企业签名和TF签名哪个好?TF签名和企业签名怎么选?

    很多开发者在App无法上架Appstore,需要内测或者开放给苹果用户使用的时候,需要选择企业签名来帮助自己的App开放下载链接,给苹果用户使用.苹果企业签名的类型有很多,TF签名最近又很火爆,那么企 ...

  2. ASP.NET Core Logging Solution

    Serilog.Extensions.Logging.File This package makes it a one-liner - loggerFactory.AddFile() - to con ...

  3. 数据结构进阶:ST表

    简介 ST 表是用于解决 可重复贡献问题 的数据结构. 什么是可重复贡献问题? ​ 可重复贡献问题 是指对于运算 \(\operatorname{opt}\) ,满足 \(x\operatorname ...

  4. 为什么我们需要Q#?

    原文地址:https://blogs.msdn.microsoft.com/visualstudio/2018/11/15/why-do-we-need-q/ 本文章为机器翻译. 你可能熟悉微软量子的 ...

  5. C#LeetCode刷题之#622-设计循环队列​​​​​​​(Design Circular Queue)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/4126 访问. 设计你的循环队列实现. 循环队列是一种线性数据结构 ...

  6. C#LeetCode刷题之#383-赎金信(Ransom Note)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3937 访问. 给定一个赎金信 (ransom) 字符串和一个杂志 ...

  7. C#LeetCode刷题之#888-公平的糖果交换(Fair Candy Swap)

    问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3758 访问. 爱丽丝和鲍勃有不同大小的糖果棒:A[i] 是爱丽丝 ...

  8. Virtuoso 中如何优化 Library Manager 的显示

    https://www.cnblogs.com/yeungchie/ 主要从 cds.lib 文件去入手. 假设现在想把 Virtuoso 预装的库整理到 preload 分类(库)中. 首先创建一个 ...

  9. 这都Java15了,Java7特性还没整明白?

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...

  10. getting session bus failed: //bin/dbus-launch terminated abnormally with the following error: Autolaunch error: X11 initialization failed.

    今天在调试dbus程序的时候,运行程序出现了getting session bus failed: //bin/dbus-launch terminated abnormally with the f ...