unity 2019 点击脚本启动不了VS_理解Unity中的优化(一):性能分析

性能分析:

所有尝试优化的操作都是从发现问题开始的,在谈论性能时,这是非常重要的。对一个应用进行性能分析,第一步是根据性能分析的结果,找出它的瓶颈。然后再优化项目中的用到的技术和资源的结构。

提示:本节性能分析中出现的方法名称,都是从unity5.3中提取的,方法名可能在以后的Unity版本中发生变化。

工具:

对于unity开发者来说,性能分析的工具有很多种。Unity有一系列的内置工具,比如CPU Profiler,Memory Profiler和5.3中新加的Memory Analyzer。

然而最好的分析数据通常来自于特定平台的工具。其中包括:

IOS:Instruments和XCode Frame Debugger

Android:Snapdragon Profiler

运行因特尔CPU/GPU的平台:VTune和Intel GPA

PS4:Razor系列

Xbox:Pix工具

这些工具通常能分析用IL2CPP打包出来的C++项目。这些本地代码版本中,能清晰的看到堆栈调用和各类方法的执行时间,如果用Mono编译,是做不到这些的。

关于IOS设备上怎么进行性能分析,Unity官方有一个基本的介绍。请看:

Profiling with Instruments – Unity Blog​blogs.unity3d.com
e24f74f023abc2d170e43832731d33dc.png

启动流程剖析:

当查看启动流程的时间时,有两个方法需要注意。在那些影响启动时间的配置文件、资源和工程代码中,这两个方法起着重要的作用。

在不同的平台上,启动时间是不同的。在大多数平台上,Splash Image显示的时间,就是启动的时间。

7c849e9093805781b22808a26517f6ef.png

上面的截图来自于在iOS设备上运行的一个示例项目。在此平台的startUnity方法中,请注意UnityInitApplicationGraphics和UnityLoadApplication方法。

UnityInitApplicationGraphics执行了大量的内部操作,例如设置图形设备和初始化许多Unity的内部系统。另外,为了初始化Resource系统,它必须加载Resource系统所包含下标的所有文件。每个名为“Resources”的文件夹中的每一个资源文件(注意:这只适用于项目“Assets”文件夹中名为“Resources”的文件夹,以及“Resources”文件夹中的所有子文件夹)都包含在Resource系统的数据中。因此,初始化Resource系统所需的时间与“Resource”文件夹中的文件数量至少呈线性关系。

UnityLoadApplication包含加载和初始化第一个场景的方法。在项目中,这包括把需要在第一个场景里需要显示的所有数据进行反序列化和实例化。比如,编译着色器,上传贴图和实例化GameObjects。另外,第一个场景中,所有继承了MonoBehaviour脚本中的Awake方法都会在这个时候被回调。

这些过程意味着,如果在项目的第一个场景中,在Awake方法中有长时间运行的代码,那么该代码就会增加项目的启动时间。为了避免这一问题,在Awake方法中不能放运行时间长的代码,或者把这些代码放到程序的其他其他生命周期里。

运行时流程分析:

在初始化启动之后的性能分析中,最主要的是PlayerLoop方法。这个是Unity的主循环,并且每一帧都会被执行一次。

395fadee62d42b7bdaa271b5365c39b1.png

上面的截图来自Unity5.4一个示例项目的性能分析。它展示了PlayerLoop中几个最有趣的方法。请注意,不同Unity版本之间,PlayerLoop中的方法名称可能有所不同。

PlayerRender是运行在Unity渲染系统中的方法。它包括对象剔除,计算动态批次,向GPU提交绘制命令。任何的后处理效果(Image Effects)或基于渲染的脚本回调(比如OnWillRenderObject)也都在这里运行。通常来讲,在具有交互的项目中,这个方法也是最影响GPU性能的。

BaseBehaviourManager调用了三个类型的CommonUpdate方法。它会调用当前场景中,挂在激活的物体上面的Monobehaviours里的特定方法。

  • CommonUpdate<UpdateManager> 回调 Update
  • CommonUpdate<LateUpdateManager> 回调 LateUpdate
  • CommonUpdate<FixedUpdateManager> 如果勾选了物理系统,就会回调 FixedUpdate

通常,检测BaseBehaviourManager::CommonUpdate<UpdateManager>这类方法是最有趣的,因为它是多数Unity项目脚本运行的入口。

有几个其他的方法也可以注意一下:

如果项目用到了Unity的UI系统,UI::CanvasManager就会回调几个不同的方法。包括Unity UI的批次计算和布局更新,在CanvasManager中,这两个方法也是比较常用并且比较重要的方法。

DelayedCallManager::Update运行协程。这部分内容在之后的”Coroutines”的章节会详细的介绍(如果我能坚持的话,哈哈哈)或者参考官方文档

Unity - Manual: Coroutines​docs.unity3d.com
13c55b89a56ff936a184901d15f41c5f.png

PhysicsManager::FixedUpdate执行PhysX物理引擎。它主要涉及到执行PhysX的内部代码,并且也手当前场景中物理对象数量的影响。比如Rigidbodies和Colliders。然而,基于物理的回调也会在OnTriggerStay和OnCollisionStay中出现。

如果项目有用到2D物理系统。那么在Physics2DManager::FixedUpdate中也会出现类似的调用。

脚本方法剖析:

当脚本用IL2CPP编译跨平台编译时,找到包含ScriptingInvocation对象这行。这是Unity为了执行脚本代码,从内部代码过渡到运行时脚本的一个时间点(注意:从技术上讲,通过运行IL2CPP,C#和JS脚本也变成了本地代码。然而,这种编译的代码主要通过IL2CPP运行时框架执行方法,这跟手写的C++代码不太相似)。

603c2eb4a438693d3a19d36156aaa4bc.png

上面的截图来自一个Unity5.4示例项目中的另一个的性能分析。RuntimeInvoker_Void这一行下面的所有方法都是C#脚本编译的,它们每帧都会被执行一次。

分析报告阅读起来比较容易:每一个都是类名+“_”+方法名。在上图中,我们可以看到EventSysten.Update,PlayerShooting.Update和几个其他的Update方法,这些是大多数MonoBehaviours脚本中比较标准的Unity Update回调。

展开这些方法,可以清楚的看到那些正在占用CPU的方法。其中也会包括项目中被用到的Unity API和C#类库的方法。

上图的分析中,也显示了StandaloneInputModule.Process,这个方法会在每一帧都用射线穿过整个UI,为了检测是否有点击事件或者滑动事件触发。这个对性能的主要影响是需要遍历所有的UI元素,并且监测鼠标的位置是否在UI元素的边界内。

资源加载:

资源加载主要是通过SerializedFile::ReadObject方法来实现的。在对CPU性能分析时,就可以找到这个方法。SerializedFile::ReadObject通过Transfer方法,把文件的二进制数据关联到Unity的序列化系统。所有的Asset类型中,都能找到这个Transfer方法,比如Texttures,MonoBehaviours 和Particle Systems。

02546ec6eabd3962ee0f2a8a0c337687.png

在上面的截图中,一个场景正在被加载。SerializedFile::ReadObject下面调用的不同Transfer方法表明了Unity正在读取并且反序列化场景中所有的Assets。

通常,如果运行时遇到了性能问题,在加载资源时帧率下降,并且通过性能分析是由于SerializedFile::ReadObject这个方法造成的。请注意,在多数情况下,只有当通过SceneManager, Resources 或者 AssetBundle API进行同步加载资源时,SerializedFile::ReadObject才会出现在主线程里。

避免出现这种性能问题,常规的做法是:你可以使用异步加载资源(这就把大量的ReadObject操作丢给了工作线程),或者提前加载好比较大的资源。

注意,当克隆objects时,Transfer也会被调用(在性能分析时出现的CloneObject就是)。如果CloneObject方法下面出现了Transfer方法,这说明资源不是正在从储存器上加载,而是在克隆老的对象。这个过程是:Unity先把老对象序列化,再反序列化数据作为新的对象。

本文翻译自Unity官方文档:

Unity - Manual: Profiling​docs.unity3d.com
13c55b89a56ff936a184901d15f41c5f.png

作者水平有限,如有错误请多加指正。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值