Hi!
文章来源:Unity: Android Optimization Guide
一切都很好,直到你意识到缺乏优化会杀死你的游戏。
介绍 就像所有在Unity中工作的人,在Android和Ios项目中,你都会在某些时候遇到性能问题,FPS下降、延迟、延迟等,这些问题会干扰你的游戏甚至会毁掉它。
你可以确定是时候深入你的项目并对其进行优化了。 这是这个指南的摘要,能帮助你更好的导航:
分析你的游戏
Unity分析器 为了观察和分析你的项目性能,你必须使用Unity分析器(Window->Profile)。它让你直观的看到你的游戏在做什么,什么比较耗时,每帧渲染需要多长时间,什么在消耗你游戏的性能。
它真的很好使用,你仅仅点击点击图形,例如尖峰图,就可以得到帧计算的细节。Unity向你展示花费最多时间的进程。为了更好的理解这些进程,立刻使用Google搜索他们的名字,你将在论坛上发现一篇相关的帖子。
Unity分析器工作在编辑器上,向你展示你的游戏正在做什么,但是要注意它并不代表你的游戏的真实性能。Unity编辑器同时处理其他的进程,而不仅仅是你的进程,因此相比于你的游戏简单编译,它会运行的比较慢。
远程分析器 这就是我们为什么必须编译你的游戏,并且从你的android设备上分析它。 一旦你已经配置了Android SDK和JDK去配置你的项目【https://docs.unity3d.com/Manual/android-sdksetup.html】,你就可以使用远程分析器。 在编译设置里(File->Build Settings…),你只需要勾选开发编译和自动连接分析器,并且确定在编辑器设置中(Edit->Project Setting->Editor)设备选项要被设置成任何android设备。
现在,你必须在你的设备上启动你的游戏,同时连接到电脑,通常你会在Unity看到分析器窗口,有你设备统计数据。 如果没有,打开分析器窗口,在“Active Profiler”下拉窗口,选择“AndroidPlayer(ADB…)”或者什么。那就是你的设备。
直接分析你的呃设备将给你提供你的游戏性能更准确的信息,所以选择这种方法。
编辑器日志 另一个可以获取构建信息的好工具是打开编辑器日志。在你编译好你的游戏之后打开控制台窗口(Window>Console),在右上角有个按钮,你可以点击它选择“打开编辑器日志”
它会打开一个有许多构建信息的文档,特别是关于构建大小的信息和占据空间的资产的信息。向下滚动文档,直到你找到像下面这样的内容:
定期在不同设备上测试 android设备的多样性是android开发的一个很大的困难,因为一个问题或者性能问题会可能会出现在一个设备上,而不会出现在其他的设备上。
这就是为什么你必须在不同的设备上测试你的游戏以防止问题的发生,并且确定它能兼容大量手机。 当然,在游戏结束时才做优化是很诱人的,但你将发现自己会陷入很多性能问题中。最好的的是定期分析你的游戏,比如在一个重要的里程碑上。事实上,游戏改动的越少,你将会越快速的找到是什么在消耗你的性能。
代码: 在进行渲染优化之前,我们希望我们的代码无可挑剔。事实上,如果你像我是一个程序员,并且你和美术一起工作,那么最好在指责美术之前先检查你的代码的性能。(即使所有的事情都确定是他们的错误。)
不要把所有的东西放在Update里。 Uniy初学者最大的错误之一就是过于依赖Update函数。很容易把所有的代码都放在它里面,检查这个或者那个并作出相应的反应,但如果在你场景中的每个GameObject都有一个Update函数去检查很东西并实现复杂的操作,这可能严重影响android性能。
所以,在使用Update函数之前,反思你的需求。它真的需要在每一帧被调用吗?
使用协程 如果不是这样,你有几个选项可以提高效率。
你可以使用协程每秒调用一个方法,例如,使用以下指令“yield return new WaitForSeconds (1);”它可以用来刷新一些UI显示:
或者你可以使用“yield return new WaitForEndOfFrame ();”等待两帧再调用你的方法。例如执行一个复杂的计算,而不是每一帧执行。
使用事件、动作和反应性编程 真正高效的是只在当你需要的时候才调用你的方法,例如当这个变量改变的时候、这个方法被调用的时候或者当事件发生的时候显示和UI弹出。。。。
这是反应性编程的原则,使用事件,其中一个动作调用反应。 在C#中你可以使用代理:https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/delegate
特别是动作代理:https://msdn.microsoft.com/en-us/library/system.action(v=vs.110).aspx
它允许你创建事件,当它们发生的时候你必须去调用它,那些事件会调用已经订阅了它的所有方法。
例如你创建了一个事件“OnPlayerJump”,在你的代码中每当你的角色跳跃的时候都会调用它,你订阅这个事件到一个方法,这个方法会去创建一些灰尘或者是一个播放跳跃声音的事件。这仅仅是个小介绍,如果你不懂,可应该去查一下。
如果你对反应编程感兴趣,可以在这个Unity 资产里查看:https://assetstore.unity.com/packages/tools/integration/unirx-reactive-extensions-for-unity-17276
使用Raycasts检查你的可触摸GameObjects 在Unity中,除了UI,没有任何简单的方法去检测屏幕上的GameObject的点击。你可以使用OnMouseDown()函数,但是Unity会在手机上阻止它的使用。
所有我们能做的就是使用Raycasts,从相机开始,到你手指触摸屏幕的地方。如果你触摸了一个对象类型,你可以调用它的一份方法。
这就是我做的,我也一个Touchable类,一份Touchable层,当屏幕上的发生触摸时,我会使用这个方法:
它检测一个可触摸的GameObject是否有触摸发生,如果发生了,我可以调用GameObject上的OnTouchDown ()方法。
物理 现在已经检查了你的代码,如果有物理交互,你肯定很想去检查一下如何去管理它们。在手机上最好什么也没有,但你必须去做,你必须小心一些简单的事情。
使用简单初级的碰撞器,而不是网格碰撞器,因为网格碰撞器的处理要复杂的多。 尽可能将“碰撞检测模式”设置为“离散”,因为“动态”要求更高的性能。 最后,你可以去TimeManager窗口(Edit>Project Settings>Time),调整”Fixed Timestep”值。这个值表示两次调用FixedUpdate()方法之间的时间间隔。
因此,如果降低Fixed Timestep, 物理计算会被频繁的调用,从而得到个更精确的模拟,但是会使用更多的资源。另一方面,提高它可能会减少你的物理模拟时间,特别的是如果你不需要特别精确的模拟。
To use, see:Jektify - Doc
Goodbye!
Put a very powerful message.