1.字符串连接的处理。因为将两个字符串连接的过程,其实是生成一个新的字符串的过程。而之前的旧的字符串自然而然就成为了垃圾。而作为引用类型的字符串,其空间是在堆上分配的,被弃置的旧的字符串的空间会被GC当做垃圾回收。
2. 尽量不要使用foreach,而是使用for。foreach其实会涉及到迭代器的使用,而据传说每一次循环所产生的迭代器会带来24 Bytes的垃圾。那么循环10次就是240Bytes。(这个在5.5版本做了优化)。
3. 不要直接访问gameobject的tag属性。比如if (Go.tag == “human”)最好换成if (go.CompareTag (“human”))。因为访问物体的tag属性会在堆上额外的分配空间。如果在循环中这么处理,留下的垃圾就可想而知了。使用tag和name都会产生GC,因为都是字符串。
4. 使用“池”,以实现空间的重复利用。
5. 如果你需要动态改变或者连接字符串,使用System.Text.StringBuilder.从内存角度考虑,字符串是奇怪的,因为它们既是堆分配的又是不可变的.string类型是分配在堆上,且不能改变的一个奇异的东西。需要动态创建string ,请使用StringBuilder类。
6. 协同会产生GC,因为Unity会产生一个实例来管理协同。协同的嵌套会产生延迟调用。yield return 0; yeild本身不会产生GC,但是因为0会被装箱(Boxing),会产生GC的。可以使用yield return null;
7.
while (!isComplete) { yield return new WaitForSeconds(1f); }
需要用new waitForSeconds缓存下来。
8. WaitForTargetFPS 就是等待垂直同步。WaitForPresent就是CPU等待GPU,GPU为瓶颈。
9. 角色材质数量2~3,骨骼数小于30,面片数300~1500。静态对象顶点小于500,UV不要越界。粒子特效满屏小于200个粒子,发射器最大粒子数不超过50,粒子要小,非常小的建议去掉alpha通道。
10. 长音频使用.ogg或Mp3,短的.wav和 .aif.
11. 关于Unity图形渲染优化:
渲染流程:Cpu确认那些需要渲染怎么渲染,发送指令给GPU,GPU执行渲染命令。
对GPU而言,减少渲染对象数量;减小远裁面距离;分层设置裁剪距离;使用遮挡裁剪。
延迟渲染Deferred rendering对高端设备使用实时光照,阴影和反射。
前向渲染 forward rendering ,更适用于低端设备,不使用这些属性的。
SkinnedMeshRenders更消耗资源,可以修改为MeshRender。将SkinnedMesh使用BakeMesh函数来创建一个匹配姿态的Mesh。SkineMeshrender和ClothmeshRender不能批处理。
**
若降低分辨率,看GPU time效率提高,就是fill rate填充速率的问题,就是每次给GPU太多的渲染像素,超过GPU的能力。
若降低画质,看GPU time时间提高,可能是内存带宽问题。方法,纹理压缩和MipMap。
**
image effects,也会造成Fillrate问题。
半透明的shader会降低可批处理的个数。
12. 帧率过低,场景内对象面数太多。
可使用MeshSimple插件来减少面数。
13. 使用Occulsing Culling来做遮罩裁剪
之前对遮罩裁剪做过说明,但是没有具体用。使用遮罩的时候,需要把它作为主场景,还必须有相机才可以。若是用其他场景来加载这个场景,场景中没有相机,则遮罩不会起作用。