UnityIn这次整理了一些程式人员在UNITY开发上与“效能”相关,需要注意的“关键点”:
暂存常用的Component:
根据官方文件的描述,每次GetComponent的呼叫,UNITY都会花点时间寻找所要求的object上。要省下这点时间,建议利用Private变数在Object Awake时,将常的用component暂存下来。
不要在任何Update的function内,使用Find:GameObject.Find这个函式用来搜寻全域、特定名称之物件,效能上有一定的损耗,所以请尽量在Start或Awake里使用,而非Update函式里。若要每个Frame搜寻请改用GameObject.FindWithTag。
多多使用BuildIn Array:
如果物件数量是固定的,type[]的写法是速度最快的选择
运算少用“除”,多用“加、减、乘”,根据UNITY官方数据:
“除法”,需要30 - 40 cycles来完成
“加、减、乘”,只需要一两个cycles
“平方根、Sin 、Cos” ,需要60 - 100 cycles来完成
单纯比较向量距离,少用Normalize:
Normalize = vec / sqrt( vec.x^2 + vec. y^2 + vec. z^2),所以尽量改用sqrMagnitude
少用Dynamic typing (JavaScript):
使用static typing可以让JavaScript的程式码跑起来跟C#一样快。依据官方数据,JavaScript在UNITY里的执行速度是一般C++的50%、比Mozllia JavaScript快20倍。
只Update在画面上或距离较近的物件,最好在需要时才开启enable
多使用Trigger或Event delegeate来触发或通知状态的改变,而非每个每个Update作检查
尽量避免每个Frame作Raycasting:
对于Mesh物件作Raycasting有一定的Cost,所以尽量避免每个Frame作Raycasting,可用Culling (Layer) mask先滤掉不必要的物件
别忽视SkinMesh与DrawCall的伤害:(Mobile Platform)
目前iPhone 3GS与Nexus One以下的机种,对于SkinMesh与DrawCall的数量还是相当敏感。以手边的测试数据来看,800面数的角色在NEXUS ONE同一画面上,维持30FPS可撑7~9只角色
少用Alpha testing,多用Alpha Blending:(Mobile Platform)
依据PVR所公布的数据,在iPhone 3GS以前的机种GPU的设计上,Alpha Testing是比Alpha Blending昂贵的
减少动态光照: (Mobile Platform)
不管是Vertex或PerPixel Lighting,都会在DrawCall上增加数量,因此对于较低阶的机种会有影响。PixleLight的部分,因为是对每个Pixel做光照计算,对GPU的影响会更胜Vertex Lighting。解决方法是将光bake到贴图上。
将Mesh compress压缩比调整到最高以降低容量:
除非发现压缩之后的Mesh出现,如:破洞、闪烁...等问题,不然尽量将这个选项设定的越高越好
手动呼叫gabage collection:
在固定时间间隔下手动呼叫System.GC.Collect(),确保记忆体的回收,如下:if( Time.frameCount % m_frameFreq == 0 ) System.GC.Collect(); 这个用法在Profiler下,可能会发现在CPU Cost上固定间隔的突波,但实际在手机上测试时,对于FPS并没有显著的影响。