zoukankan      html  css  js  c++  java
  • Unity开发Android应用优化指南(上)

    http://forum.china.unity3d.com/thread-27037-1-2.html

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


    游戏性能分析

    Unity Profiler

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

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



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

    Remote Profiler

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

    在Build Settings中(File > Build Settings)同时勾选 “Development Build” 和 “Autoconnect Profiler”,并确保 Editor Settings 设置中的 “Device” 一栏为 “Any Android Device”。



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

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

     
    选择设备作为“Active Profiler”


    编辑器日志

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

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

     
    在不同设备上进行测试


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

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

    脚本

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

    慎用Update

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

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

    使用协程

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

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



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



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

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

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

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

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

    利用射线检测可触摸GameObject

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

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



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

    物理

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

    动态刚体(Rigidbody)的数量越少越好,它们会大量消耗计算性能。
    使用基础碰撞体,避免使用网格碰撞体,后者的计算处理要复杂得多。
    尽量将“Collision Detection Mode” 设置为 “Discrete”,因为 “Dynamic” 会用掉更多的性能。
    最后,可以在TimeManager窗口(Edit > Project Settings > Time)中设置 “Fixed Timestep” 的值。这个值表示两次FixedUpdate()调用之间的时间间隔。



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

    总结

    以上就是Niels从刚做完的Android项目中学到的经验,并将其总结在这篇文章里,以帮助其他更多的Unity开发者。优化通常需要花费大量时间来寻找性能瓶颈并进行测试,希望这篇文章对正在使用Unity进行开发的朋友们有帮助。我们还会分享一些Unity项目制作及优化经验在Unity官方中文社区(unitychina.cn),请保持关注!
  • 相关阅读:
    关于同余最短路
    【水】关于 __attribute__
    题解【AtCoder
    一些简单图论问题
    浅谈简单动态规划
    关于博客园主题(美化博客园)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第47章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第46章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第45章 读书笔记(待更新)
    Algebra, Topology, Differential Calculus, and Optimization Theory For Computer Science and Machine Learning 第44章 读书笔记(待更新)
  • 原文地址:https://www.cnblogs.com/nafio/p/9137090.html
Copyright © 2011-2022 走看看