我们在游戏开发过程中,优化性能是极为重要的一个环节。众所周知“特效”是性能优化的一个重点。据说,特效文件中的发射粒子数在50以上就会存在性能问题。于是,针对此问题我们可以做一个工具,查找出项目中所有的特效发射粒子数,根据数量从大到小排序,并标志定位到相应的特效文件。
思路步骤如下:
1. 在Editor文件夹下新建一个脚本文件,命名为EffectEmitChecker.cs
2. Resource.LoadAll所有的特效文件存入一个数组
3. 循环遍历特效数组并PrefabUtility.InstantiatePrefab()生成一个实例
4. 获取ParticleEmitter组件,并把相关信息缓存到一个List中
5. DestroyImmediate()删除生成的实例
6. List根据发射粒子数大小排序
7. 在OnGUI()中展示List中的数据
具体代码如下:
using UnityEngine;
using System.Collections;
using UnityEditor;
using System.Collections.Generic;
public class EffectEmitChecker : EditorWindow
{
float ThumbnailWidth = 40;
float ThumbnailHeight = 40;
GUIStyle style = new GUIStyle();
Vector2 vec2 = new Vector2(0, 0);
List<EffectParticle> listEffect = new List<EffectParticle>(); //缓存特效信息
[MenuItem("Effect/Effect Emit Checker")]
static void MainTask()
{
EffectChecker window = GetWindow<EffectChecker>();
window.LoadEffect(); //加载特效
window.Show();
}
void OnGUI()
{
ListEffect();
}
void LoadEffect()
{
Object[] objs = Resources.LoadAll("Effects/"); //读取所有特效文件,可以根据情况改变地址
for (int i = 0; i < objs.Length; i++)
{
GameObject go = PrefabUtility.InstantiatePrefab(objs[i]) as GameObject; //创建实例
if (go == null) continue;
ParticleRenderer[] renderers = go.GetComponentsInChildren<ParticleRenderer>(true); //获取特效实例下的所有ParticleRenderer组件
foreach (ParticleRenderer render in renderers)
{
EffectParticle effect = new EffectParticle();
ParticleEmitter emitter = render.GetComponent<ParticleEmitter>(); //获取ParticleEmitter组件
effect.name = objs[i].name;
effect.material = render.sharedMaterial;
if (emitter != null)
{
effect.maxEmission = emitter.maxEmission; //最大发射粒子数赋值
}
effect.prefab = objs[i];
listEffect.Add(effect);
}
DestroyImmediate(go); //销毁实例
}
listEffect.Sort((x, y) => { return y.maxEmission.CompareTo(x.maxEmission); }); //从大到小排序
style.normal.textColor = Color.red;
style.fixedWidth = 120;
}
void ListEffect()
{
vec2 = EditorGUILayout.BeginScrollView(vec2);
foreach (EffectParticle effectParticle in listEffect)
{
if (effectParticle != null)
{
GUILayout.BeginHorizontal();
Material mat = effectParticle.material;
if (mat != null)
{
//根据材质找到相应的纹理显示
Texture texture = mat.mainTexture;
if (texture != null)
GUILayout.Box(texture, GUILayout.Width(ThumbnailWidth), GUILayout.Height(ThumbnailHeight));
else
GUILayout.Box("N/A", GUILayout.Width(ThumbnailWidth), GUILayout.Height(ThumbnailHeight));
GUILayout.Label("Shader:" + mat.shader.name, GUILayout.Width(140)); //Shader名称
//特效主颜色显示
if (mat.HasProperty("_Color"))
EditorGUILayout.ColorField(mat.color, GUILayout.Width(50));
else if (mat.HasProperty("_TintColor"))
EditorGUILayout.ColorField(mat.GetColor("_TintColor"), GUILayout.Width(50));
else
GUILayout.Box("N/A", GUILayout.Width(50));
}
//发射粒子数判断
float emission = effectParticle.maxEmission;
if (emission < 50)
GUILayout.Label("MaxEmission:" + emission.ToString(), GUILayout.Width(120));
else
GUILayout.Label("MaxEmission:" + emission.ToString(), style); //字体标红
//特效名称,并可定位到相应文件
if (GUILayout.Button(effectParticle.name))
Selection.activeObject = effectParticle.prefab;
//文件所在路径节点
GUILayout.TextField("Node:" + effectParticle.hierarcyPath);
GUILayout.EndHorizontal();
}
}
EditorGUILayout.EndScrollView();
}
//特效信息实体类
class EffectParticle
{
public string name;
public Material material;
public float maxEmission;
public Object prefab;
public bool bScaleWithTransform;
public EffectParticle()
{
maxEmission = 0;
}
}
}
查出来的特效发射粒子数就可以很理直气壮的和特效师说:你的这个特效有性能瓶颈,赶紧优化一下吧。他会很诧异你怎么能如此快速精准地查找出特效发射粒子数,并很开心地向你索要这个工具的。
Ricky Yang个人原创,版权所有,转载注明,谢谢。http://blog.csdn.net/yangyy753