时间:2017-11-12来源:本站原创作者:佚名

如今越来越多的开发者使用Unity开发Android及iOS项目,开发过程中难免会遇到一些性能方面的问题,例如掉帧、延迟和卡顿等等,导致游戏体验变差甚至毫无游戏体验可言。今天这篇文章将由NielsTiercelin,为大家分享深入剖析Unity项目优化过程的上半部分。

游戏性能分析

UnityProfiler

建议使用UnityProfiler工具(WindowProfiler)来分析项目性能,该工具以图形化的方式呈现游戏具体的行为、计算所需的时间以及每帧渲染的时长等等,包含所有可能会影响性能的数据。

使用该工具非常简单,只需点击图表本身(例如点击图表中的某个高峰)就可以查看该帧的详细计算数据。Unity会显示耗时最长的处理步骤。如果并不理解其中某个处理步骤的意义,也很容易在网上搜索来查找相关内容。

UnityProfiler本身在编辑器环境下运行,并展示游戏运行的细节,但请注意,这里并不能反映出游戏的真实性能。由于Unity编辑器需要处理游戏本身以及额外的内容,因此此时的游戏运行速度会比构建之后的游戏慢一些。

RemoteProfiler

使用UnityProfiler无法得知游戏运行的真实性能,所以需要在设备上运行游戏并进行分析。下面以Android设备为例,配置AndroidSDK和JDK后构建项目,然后就可以开始使用RemoteProfiler了。

在BuildSettings中(FileBuildSettings)同时勾选“DevelopmentBuild”和“AutoconnectProfiler”,并确保EditorSettings设置中的“Device”一栏为“AnyAndroidDevice”。

现在将设备连接到计算机并运行游戏。正常情况下Unity中会出现Profiler窗口,显示设备的运行状态。如果Profiler窗口未出现,则打开Profiler窗口,在“ActiveProfiler”下拉菜单中选择类似“AndroidPlayer(ADB…)”的条目,这个一般就是您的设备。

直接对设备本身进行分析可以更精确地获取游戏的性能数据,因此优先考虑这种方法。

选择设备作为“ActiveProfiler”

编辑器日志

另一种获取信息的方式是编辑器日志。游戏构建完毕后立刻打开Console窗口(WindowConsole),在窗口的右上方有一个按钮,点击后选择“OpenEditorLog”。

此时系统会打开一个文档,其中包含很多构建相关的信息,特别是构建文件的大小以及资源占据的空间等。

在不同设备上进行测试

Android开发相当复杂,可能会出现很多问题。因为某个性能问题可能仅在某些设备上出现,而在另外一些设备上完全不是问题。因此应该在不同设备上测试游戏,从而避免此类问题,保证您的游戏能够在绝大多数设备上正常运行。

虽然等到项目开发后期再做优化这种想法很常见,但此时的性能问题可能已堆积成山。因此最好的做法是周期性地检测游戏,例如在每个里程碑达成时进行性能分析。这样随着游戏不断修改,需要进行的优化工作也会越来越少,也能越来越快地找到性能瓶颈所在。

脚本

搞定渲染优化这个大目标之前,应该先保证脚本不会出现问题。如果您是程序员,最好在把锅甩给美术之前先检查一下脚本是否有性能问题(哪怕真的是美术的锅!)

慎用Update

Unity初学者通常最大的误解在于过于依赖Update()函数。将所有内容都塞到Update()中确实是最容易的做法,例如检查某个状态并根据状态做出相应动作等,但如果场景中的每个GameObject都要在Update()里检查非常多的东西或进行复杂操作,就会大大影响游戏性能。

所以,在使用Update()之前,首先问一问自己,要实现的功能真的需要逐帧运行吗?

使用协程

如果不是必须逐帧运行,还可选择其他几种方式来实现。例如,可以利用协程(Coroutines)让某个方法每秒钟运行一次:“yieldreturnnewWaitForSeconds(1);”

可以用下面的方法刷新UI:

还可以每两帧调用一次方法来进行某种复杂计算,如下:

善用Events、Actions,响应式编程(ReactiveProgramming)

调用方法真正高效地方式是仅在需要时调用。例如当某个变量改变时、某个方法被调用时,或者某个事件发生并弹出UI菜单时等等。这就是响应式编程的基本原理,即利用Events,对某个事件作出反应。

在C#中您可以使用委托,尤其是Action委托,来创建事件。当事件发生时调用某个函数,然后由该函数去调用订阅了该事件的方法。

例如,创建“玩家跳跃”事件,在代码中每当玩家跳跃时就会发起这个事件。例如某个方法生成了一些灰尘效果或者播放跳跃音效,将该方法订阅到“玩家跳跃”这个事件上,玩家跳起来时就会调用生成灰尘效果播放音效的方法。这仅仅是一种简单的应用,您还可以深入探究。

如果您对响应式编程有兴趣,可以参考UniRx-ReactiveExtensions插件。这是为Unity设计的响应式编程拓展,支持LINQ异步及多线程、LINQ订阅到事件等等。

利用射线检测可触摸GameObject

在Unity中,除了UI之外并没有什么比较容易的办法来检测某个GameObject在屏幕上的点击。OnMouseDown()函数对于移动平台并不生效。一种可行的方案是使用射线。从摄像机出发,以屏幕上手指点击的位置为方向。如果射线检测到某个对象则调用该对象的方法。

可以先定义一个Touchable类,一个Touchable层。触摸到某个对象时则调用下面的方法:

如果检测到触摸操作作用在带有Touchable的游戏对象上,则调用该对象的OnTouchDown()方法。

物理

检查脚本时一定要检查物理交互相关的代码(如果存在)。当然,移动设备上最好不要有此类代码,但如果无法避免,应特别注意以下几点:

动态刚体(Rigidbody)的数量越少越好,它们会大量消耗计算性能。

使用基础碰撞体,避免使用网格碰撞体,后者的计算处理要复杂得多。

尽量将“CollisionDetectionMode”设置为“Discrete”,因为“Dynamic”会用掉更多的性能。

最后,可以在TimeManager窗口(EditProjectSettingsTime)中设置“FixedTimestep”的值。这个值表示两次FixedUpdate()调用之间的时间间隔。

所以FixedTimestep值越小表示函数调用越频繁,从而获得更精确的模拟计算结果,代价则是消耗更多的资源。反之,该值越大越能降低处理物理相关数据所占用的时间,如果不需要特别精确的计算结果这也是一个很好的选择。

总结

本文暂时为大家分享到这里,下一篇将继续为大家讲解。优化通常需要花费大量时间来寻找性能瓶颈并进行测试,希望这篇文章对正在使用Unity进行开发的朋友们有帮助。我们还会分享一些Unity项目制作及优化经验在Unity官方中文社区(unitychina.cn),请保持







































北京哪里治疗白癜风比较好
北京治疗白癜风需要多少钱

转载请注明原文网址:http://www.helimiaopu.com/bbqb/5691.html

------分隔线----------------------------