1、Draw Call 

2、资源(模型、贴图、粒子)

3、渲染(相机,光照,Shader)

4、网络

5、代码(代码编写,资源加载,物理系统)

可以在Profiler窗口查看项目性能消耗主要在那几个地方,然后有针对性的进行优化

下面给大家分享一些常用的代码方面的内容

1、在场景中有大量物体频繁的激活或隐藏时,不适用SetActive(),在需要隐藏的时候移除屏幕,显示的时候移到屏幕内(也就是修改物体的位置)。还有一个方法,就是把需要隐藏的物体设置为一个已经隐藏的物体的子物体(父物体是隐藏的,子物体自然也看不到),这种方法和SetActive()方法差不多,不推荐使用。

2、动态实例化到场景中的物体,名字都会有一个后缀(Clone),但是为了方便识别,会修改它的名字,这样同样会产生性能消耗。

3、在不影响正常运行结果的情况下,减少对Update或者FixUpdate的调用次数

假设显示将所有的Update刷新逻辑写在RefreshUpdate中

void RefreshUpdate()
{
Debug.Log("RefreshUpdate");
}

3-1每隔一定帧数,执行一次RefreshUpdate();

int SpaceCount=10;
int UpdateCount;
void Update()
{
if(UpdateCount % SpaceCount==0)
{
UpdateCount =0;
}
UpdateCount ++;
}

3-2使用协程While(true)循环,每次循环间隔一定的时间,调用RefreshUpdate(),需要在Satrt函数中开启协程

float SpaceTime=0.1f;
IEnumerator StartUpdate()
{
While(true)
{
RefreshUpdate();
yield return new WaitForSeconds(SpaceTime);
}
}

3-3 使用InvokeRepeating循环调用RefreshUpdate();

float RepaetTime=0.1f;
void Start()
{
InvokeRepeating("RefreshUpdate",0,RepaetTime);
}

4、使用对象池

操作目标相对较少,可简化对象池,实现效果。

5、音效播放时,为避免频繁创建、销毁播放器,可以对音效统一管理

6、场景中经常需要动态生成GameObject,当一次创建的数量交多的时候,在不影响使用的情况下,可以使用协程,在多帧内完成创建

7、部分简单的物理计算可以不适用Unity提供的物理系统,简化物理计算量

8、选择合理的数据结构存储数据

9、尽量避免在Update和for循环内创建临时变量

10、尽量避免创建临时字符串

11、能使用for循环的,就不用foreach

12、每个继承MonoBehaviour的类,都会自动生成Update方法,但是很多类是使用不到Update的,这个时候需要将其删除,毕竟实时调用孔方法,多少还是有消耗的。

13、数值计算中使用乘法而不用除法,比如:A/2,可以写成A*0.5F;

14、在比较Tag的时候,使用if(gameObject.CompareTag("Tag")),而不是if(gameObject.tag=="Tag")

15、只在一个脚本中使用OnGUI方法;

16、避免在OnGUI中对变量、方法进行更新、赋值,输出变量建议在Update内;

17、同一脚本中频繁使用的变量建议声明其为全局变量,脚本之间频繁调用的变量或方法建议声明为全局静态变量或方法;

18、不要去频繁获取组件,将其声明为全局变量;

19、数组、集合类元素优先使用Array,其次是List;

20、脚本在不使用时脚本禁用之,需要时再启用;

21、可以使用Ray来代替OnMouseXXX类方法;

22、对于不经常调用或更改的变量或方法建议使用Coroutines & Yield;

23、尽量直接声明脚本变量,而不使用GetComponent来获取脚本;

24、尽量使用整数数字,因为iPhone的浮点数计算能力很差;

25、不要使用原生的GUI方法;

26、不要实例化(Instantiate)对象,事先建好对象池,并使用Translate“生成”对象;