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“生成”对象;