Unity学习-优化_卡顿原因定位以及优化方案

除了Unity的一些组件优化技巧之外,更多的细节处于代码层面上

最近学习优化,看到一篇文章,写的很详细,从底层原理到我们

的实际处理,都有一些非常好的建议,可以推荐给小伙伴们看看

https://www.jianshu.com/p/289de89a6609

===========如何定位程序的哪一个环节产生了过大的开销============

使用Uinty的Profiler工具,可以比较精准快速的定位程序的哪一个位置产生了大开销

首先在build setting里面勾选Autoconnect Profiler

然后在windows栏选择proflier即可

打开之后即可监控游戏每一帧的运行状态了,可以根据FPS和每一帧运行的时间判断游戏的卡顿程度

确定某一帧的占用率过高之后

点击波状图,就会暂停游戏

下方就会列出当前游戏运行的消耗详细信息了

跟进total栏的百分比,即可定位是哪个位置产生了最大的消耗,从而进行相应优化了

这个工具是用来定位优化点的,具体的优化方案可以参考下面的优化方式

由于篇幅有限,而且这个工具应该大部分人都知道而且会用,就不过多赘述了。

不明白的可以参阅这篇作者的 https://www.jianshu.com/p/a7cee5e548cf

写的非常详细

==================代码层优化====================

一、内存管理

  1:GC原理

      C#的垃圾回收是自动托管的,垃圾回收系统也有一套生命周期和统计流程,下面就是关于GC的整体流程:

    1)一次GC的过程分为2个阶段:

    标记清除阶段,GC会假设堆中所有对象都可以被回收,然后找出不能回收的对象,打上清除标记,剩下的就是要被回收的了。找的过程就是检查对象  有没有被其他的对象引用的过程,如果这个对象在程序中没有被引用到,那么就会被打上清除的标记。

    重新地址排列阶段,标记清除的对象被清除之后,堆里面的空间就会变成不是连续的了,GC的第二部就会开始重新排列还存在的对象,使堆中的地址  分配变成连续的。

    2)整个.net的GC流程:

    在进行.Net的GC阶段,是不止一次GC操作的,C#采用了分代算法,先对程序里面的内存进行分代管理,再根据不同的代,进行不同力度的清理。

这里面的生命周期为3代, 第0代是新创建的代码,在达到了0代集合的阈值之后,触发0代的GC,幸存的对象会进入1代集合, 同理,在1代集合达到了阈值    的时候,也会进行GC,但是这次GC是 0代和1代一起执行,以此类推,2代集合GC的时候也会进行1代 2代的CG操作。按消耗量的比例应该是 1:10:100

这种分代算法是基于 老的对象生命周期一般都比新的对象生命周期长,就像公司的员工一样,时间较长的员工公司看来一般都比新进来的员工稳定性要大。

2:优化策略

    明白了大致GC的流程之后会发现,GC会消耗大量的CPU性能,因为这里面会经历很多次的运算以及遍历等

    接下来是弄清楚GC什么时候被触发,以及如何规避影响用户体验的GC操作

    何时会触发GC?

    三种情况下会触发GC:

    1:跟进分代算法,在容量达到阈值的时候会发生,

    2:GC会不时的自动运行(频率因平台而异)。

    3:手动强制调用GC

大致的优化思路就是 降低每一次GC的运行时间(减少垃圾对象,使GC的过程中尽量少的遍历),降低GC的频率(降低触发GC机制的次数),在加载地图等需要用户等待的游戏流程里面主动GC。

     接下来就是跟进3种触发机制做我们代码上的优化了

  1)、尽量少new不必要的字段

 1 object obj = null;
 2 update()
 3 {
 4      object = somebody;
 5 }
 6
 7 update()
 8 {
 9     object obj =somebody;
10 }

      上面的赋值方式只会在开辟一个内存空间,第二种会反复开辟内存空间,这些空间一般在一代GC里面就会被释放掉。属于最无用的代码方式(没必要的  情况下)。

  2).使用对象池

    对象池的使用会大大降低新内存空间的使用,他会在一个内存空间反复给新的值。

3).尽量使用缓存机制,少使用Instantiate实例化新对象,因为这里Unity会初始化他身上的组件以及各种序列化的操作,各个物体会根据自身的组件,创建耗时都  不相同

4).字符串的操作

string的拼接操作是在内部重新new 一个新的出来,因为string在C#是不可变更到,所以在每一次的+= 就相当于new了一个新的字符串出来,如果出现比较频繁   的拼接操作,stringBuilder会比string 更好,但是string在对字符串的操作上会比stringBuider好,至于使用哪一种就看具体的需求了。

5).在地图加载等需要等待的过程中主动进行GC。

避免内存消耗还有很多的方式,我也是刚刚开始比较全面的学习性能优化,在以上也是我在网上搜集了一些自己能理解的处理方式。

CPU性能管理:

一、代码层:

  1、 尽量避免空的Update(),只要写了Update(),不管是不是空的,Unity都会去执行,这里会增加开销

  2、Find  getcomponent 等查找的方法,Unity都会去遍历场景对象和组件,在大型项目中,场景对象一旦变多就会产生很大的开销了,尽量在start里面调用而不  是update里面反复使用

3、Update里面尽量少做遍历,一次UpDate 就会遍历一次,这是一个很大的开销了。

4、在业务需求不影响的情况下,可以让Update里面的逻辑使用计时器,增加间隔,1秒调用一次,2秒调用一次等。

5、在可以知道触发条件的情况下,尽量使用委托的方式处理触发效果,而不是一次次的遍历目标的触发状态

6、和上面一样,尽量在设计代码的时候,使用观察者模式,理论上来说,游戏的大部分逻辑都可以使用触发后再执行,特别是UI。(在使用lua热更新的项目      中,大部分的游戏逻辑流程都是通过事件消息的触发来完成的,因为里面没有Uinty那么专业的生命周期)

7、for 和 foreach 的取舍 :

    在固定长度或长度不需要计算的时候for循环效率高于foreach.

    在不确定长度,或计算长度有性能损耗的时候,用foreach比较方便

二、渲染层:

渲染层的优化包括 图集的结构设计、模型的处理、LOD、mipMap、烘焙等、阴影处理

图集的结构设计是为了减少额外的draw call,尽量以模块划分,因为原则上每个模块之间的UI元素是不会互相耦合的。Unity的texture的大小是根据2的幂来计算到。如果你的图片真实大小是1025,那么他会创建一块2048的texture,也是浪费开销的行为。

模型的处理要结合LOD的使用,在固定视角、固定摄像机深度的游戏中,LOD的发挥效果不是很大,更多的是制作模型的时候就确定了模型精度

LOD和MipMap的使用会带来很大的性能提升,但是会受项目影响,具体看项目而定

烘焙就是在游戏发布之前,场景融合光照提前产生新的贴图,使这个场景不用进行动态光照计算 就可以达到光照的效果,降低了CPU计算的开销,但是对用户的体验肯定没有实时光照那么好,一般都是出现在手游中

阴影和烘焙的道理差不多,为了降低实时光照的计算量,可以将阴影设置为假阴影,阴影在是圆的情况,不会产生旋转的变化,同时因为烘焙的原因,光线没有入射角的变化,也不会产生阴影的投射角度变化,也是在优化性能上比较常用的方式

原文地址:https://www.cnblogs.com/leixuan111/p/10737143.html

时间: 2024-08-01 06:12:39

Unity学习-优化_卡顿原因定位以及优化方案的相关文章

直播卡顿原因详解及优化

随着视频直播的发展,很多直播团队可能会遇到视频直播卡顿,频繁出现缓冲标志或者直播画面一卡一卡等情况.究竟是哪些原因造成了视频直播观看的卡顿情况呢? 又拍直播云结合实践经验,从设备.视频流.网络这三方面进行解剖分析造成直播卡顿的问题及其解决方法. 视频直播卡顿原因 造成直播视频卡顿的原因主要有设备.视频流.网络这三方面的问题. 问题排查及解决方法 设备 高清视频往往会给硬件带来解码压力,由于解码造成的卡顿尤为明显.同时如果PC端Flash Player或移动端播放软件版本过低,可能也会造成解码问题

iOS开发——项目实战总结&UITableView性能优化与卡顿问题

UITableView性能优化与卡顿问题 1.最常用的就是cell的重用, 注册重用标识符 如果不重用cell时,每当一个cell显示到屏幕上时,就会重新创建一个新的cell 如果有很多数据的时候,就会堆积很多cell.如果重用cell,为cell创建一个ID 每当需要显示cell 的时候,都会先去缓冲池中寻找可循环利用的cell,如果没有再重新创建cell 2.避免cell的重新布局 cell的布局填充等操作 比较耗时,一般创建时就布局好 如可以将cell单独放到一个自定义类,初始化时就布局好

android问题及其解决-优化listView卡顿和怎样禁用ListView的fling

问题解决-优化listView卡顿和怎样禁用ListView的fling 前戏非常长,转载请保留出处:http://blog.csdn.net/u012123160/article/details/47720257 问题产生 这算是刚到实习公司接触到的第一个任务.公司某一产品中某个界面的listView高速滑动会有卡顿的现象发生,我的任务就是解决它. 产生原因分析 我一開始的想法比較简单.可能是listview的优化没有做到位,比如convertView的复用.viewHolder的使用等等基础

Android中app卡顿原因分析示例

在知乎回答了一个“为什么微博的app在iPhone比Android上流畅”的问题.后面部分是一个典型的动画卡顿的性能分析过程,因此帖在这里.有编程问题可以在这里交流.知乎链接. ========================================================= 我来说下我所知道的事情.我不知道iOS为什么流畅,但我知道一些Android为什么不流畅的原因. 首先,就题主所说的问题,我用iPad和小米Pad对比了一下微博滑动滚屏这件事情(2014年8月10日目前微博

android问题及其解决-优化listView卡顿和如何禁用ListView的fling

问题解决-优化listView卡顿和如何禁用ListView的fling 前戏很长 问题产生 这算是刚到实习公司接触到的第一个任务.公司某一产品中某个界面的listView快速滑动会有卡顿的现象发生,我的任务就是解决它. 产生原因分析 我一开始的想法比较简单,可能是listview的优化没有做到位,例如convertView的复用.viewHolder的使用等等基础的优化措施,然并卵.好长时间后终于找到了问题发生的相关代码...经过在可疑语句上(onTouchEvent方法中的几个case.on

面试必备】深入分析App卡顿原因及优化建议

从这篇文章中你能获得这些料: 知道setContentView()之后发生了什么? 知道Android究竟是如何在屏幕上显示我们期望的画面的? 对Android的视图架构有整体把握. 学会从根源处分析画面卡顿的原因. 掌握如何编写一个流畅的App的技巧. 从源码中学习Android的细想. 收获两张自制图,帮助你理解Android的视图架构.从setContentView()说起 public class AnalyzeViewFrameworkActivity extends Activity

下载到99.5卡顿问题定位结论

近日升级包下载过程中发现一例问题:升级包下载到99.5卡顿,然后报无法获取网络资源.本文对该问题的做详细定位和总结. 问题原因:下载过程中断网,由于批量写入,因此下载浮标位置更新了,而实际上有一段数据未写入.此时下载完毕了,而系统计算只有99.5左右(有一段数据丢失).此时服务器上已经无数据可下,而系统由于见到到下载进度未到100%,还在持续刷新,刷新超过2分钟发现进度仍没有增加,因此定为网络资源的问题. 下载过程中如果出现退出下载,重新进入,系统会根据前报的进度进行继续下载,因此造成局部数据重

Android卡顿优化:卡顿分析方法

基础知识在具体讲卡顿工具前,你需要了解一些基础知识,它们主要都和 CPU 相关.造成卡顿的原因可能有千百种,不过最终都会反映到CPU 时间上.我们可以把 CPU 时间分为两种:用户时间和系统时间.用户时间就是执行用户态应用程序代码所消耗的时间:系统时间就是执行内核态系统调用所消耗的时间,包括 I/O.锁.中断以及其他系统调用的时间. CPU 性能在开发过程中,我们可以通过下面的方法获得设备的 CPU 信息.// 获取 CPU 核心数cat /sys/devices/system/cpu/poss

Windows资源管理器打开文件夹卡顿原因及解决办法

全新安装的 Win8 打开文件夹居然会卡顿,特别是打开EXE程序比较多的文件夹,通过资源监视器查看,幕后凶手就是 Windows Defender 杀毒软件. MSE是微软提供防毒功能,而Windows Defender则是为用户提供反间谍功能,Win8已经把这两个功能合二为一了.用过MSE的用户就知道它有卡EXE的毛病,在Win8中也是这样,当你打开EXE程序.压缩包比较多的文件夹,它就一直扫描啊扫描-..所以MSE很忙-.. 解决方法: 先用Windows Defender全盘扫描,然后可以