检查统计项目中Shader的使用情况,以及变体数量。
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;
public class ShaderCheck
{
private static List
private static List
private static List
private static void CollectShaderInfo()
{
m_normal_shaders.Clear();
m_build_in_shaders.Clear();
m_standard_shaders.Clear();
List
List
for (int i = 0; i < all_mats.Count; i++)
{
var mat_info = all_mats[i];
var shader_name = mat_info.Material.shader.name;
var shader_info = SelectShaderInfo(shader_name, all_sharders);
if (shader_info == null)
{
shader_info = new ShaderCheckInfo
{
Name = shader_name,
VariantCount = GetBuildInShaderVariantCount(shader_name)
};
if (shader_name == "Standard")
FillData(shader_name, m_standard_shaders, shader_info, mat_info);
else
FillData(shader_name, m_build_in_shaders, shader_info, mat_info);
}
else
{
FillData(shader_name, m_normal_shaders, shader_info, mat_info);
}
EditorUtility.DisplayProgressBar("Checking Shader", "checking", (float)(i) / (float)all_mats.Count);
}
m_standard_shaders.Sort(new ShaderCheckInfoCompare());
m_build_in_shaders.Sort(new ShaderCheckInfoCompare());
m_normal_shaders.Sort(new ShaderCheckInfoCompare());
EditorUtility.ClearProgressBar();
}
[MenuItem(ToolDes.Shader_Import)]
public static void Import()
{
if (EditorUtility.DisplayDialog("Improt Shader", "确定要导入GraphicSetting中么?", "是的"))
{
List
SerializedObject graphicsSettings = new SerializedObject(AssetDatabase.LoadAllAssetsAtPath("ProjectSettings/GraphicsSettings.asset")[0]);
SerializedProperty it = graphicsSettings.GetIterator();
SerializedProperty dataPoint;
while (it.NextVisible(true))
{
if (it.name == "m_AlwaysIncludedShaders")
{
it.ClearArray();
for (int i = 0; i < using_shader.Count; i++)
{
it.InsertArrayElementAtIndex(i);
dataPoint = it.GetArrayElementAtIndex(i);
dataPoint.objectReferenceValue = Shader.Find(using_shader[i]);
}
graphicsSettings.ApplyModifiedProperties();
}
}
}
}
private static List
{
CollectShaderInfo();
List
foreach (var shader in m_build_in_shaders)
{
shaders_name_list.Add(shader.Name);
}
return shaders_name_list;
//List
//var mats = AssetDatabase.FindAssets("t:material");
//int index = 0;
//foreach (var mat in mats)
//{
// index++;
// var path = AssetDatabase.GUIDToAssetPath(mat);
// var real_mat = AssetDatabase.LoadAssetAtPath
// if (real_mat != null)
// {
// if (real_mat.shader.name == "Standard")
// {
// continue;
// }
// if (!shaders_name_list.Contains(real_mat.shader.name))
// shaders_name_list.Add(real_mat.shader.name);
// }
// EditorUtility.DisplayProgressBar("Checking Shader", "import_shader:" + path, (float)(index) / (float)mats.Length);
//}
//EditorUtility.ClearProgressBar();
//return shaders_name_list;
}
[MenuItem(ToolDes.Shader_Check)]
public static void Check()
{
CollectShaderInfo();
var title = "材质总数: " + GetAllMaterialInfo().Count
+ " 使用Shader总数: " + (m_normal_shaders.Count + m_standard_shaders.Count + m_build_in_shaders.Count)
+ " BuildIn_Shader总数: " + m_build_in_shaders.Count
+ " Project_Shader总数: " + m_normal_shaders.Count;
//导出
ExprotDescription(GetDescription(m_normal_shaders, m_standard_shaders, m_build_in_shaders), title);
}
private static void FillData(string shader_name, List
{
var s_shader_info = SelectShaderInfo(shader_name, shaders);
if (s_shader_info == null)
{
shader_info.m_mat_info.Add(mat_info);
shaders.Add(shader_info);
}
else
{
s_shader_info.m_mat_info.Add(mat_info);
}
}
private static List
{
List
var mats = AssetDatabase.FindAssets("t:material");
int index = 0;
foreach (var mat in mats)
{
index++;
var path = AssetDatabase.GUIDToAssetPath(mat);
var real_mat = AssetDatabase.LoadAssetAtPath
MaterialCheckInfo info = new MaterialCheckInfo();
info.Name = real_mat.name;
info.Path = path;
info.Material = real_mat;
materials.Add(info);
EditorUtility.DisplayProgressBar("Checking Shader", "get_materials:" + path, (float)(index) / (float)mats.Length);
}
EditorUtility.ClearProgressBar();
return materials;
}
private static List
{
List
var method = GetVariantCountMethodInfo();
var shader_list = AssetDatabase.FindAssets("t:Shader");
int index = 0;
foreach (var shader in shader_list)
{
index++;
var path = AssetDatabase.GUIDToAssetPath(shader);
Shader target_shader = AssetDatabase.LoadAssetAtPath
var count = method.Invoke(null, new System.Object[] { target_shader, true });
ShaderCheckInfo info = new ShaderCheckInfo();
info.Name = target_shader.name;
info.Path = path;
info.VariantCount = (ulong)count;
shaders.Add(info);
EditorUtility.DisplayProgressBar("Checking Shader", "get_shaders:" + path, (float)(index) / (float)shader_list.Length);
}
EditorUtility.ClearProgressBar();
return shaders;
}
private static ulong GetBuildInShaderVariantCount(string shader_name)
{
var method = GetVariantCountMethodInfo();
Shader target_shader = Shader.Find(shader_name);
var count = method.Invoke(null, new System.Object[] { target_shader, true });
return (ulong)count;
}
private static MethodInfo GetVariantCountMethodInfo()
{
Assembly asm = Assembly.LoadFile(@"D:\work_tool\unity_2018.3.6f1\Unity\Editor\Data\Managed\UnityEditor.dll");
System.Type shader_util = asm.GetType("UnityEditor.ShaderUtil");
MethodInfo method = shader_util.GetMethod("GetVariantCount", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
return method;
}
private static ShaderCheckInfo SelectShaderInfo(string shader_name, List
{
foreach (var item in shaders)
{
if (item.Name == shader_name)
{
return item;
}
}
return null;
}
private static List
{
List
des.Add("Standard Shader:" + "\r\n");
foreach (var item in standard_shaders)
{
des.Add(item.ToString());
}
des.Add("Build_In Shader:" + "\r\n");
foreach (var item in build_in_shaders)
{
des.Add(item.ToString());
}
des.Add("Normal Shader:" + "\r\n");
foreach (var item in normal_shaders)
{
des.Add(item.ToString());
}
return des;
}
private static void ExprotDescription(List
{
var save_path = Application.dataPath + "/shader_report.txt";
FileUtil.Export(save_path, des, title);
}
}
public class MaterialCheckInfo
{
private string m_name = ""; //材质名称
public string Name { get { return m_name; } set { m_name = value; } }
private string m_path = ""; //材质路径
public string Path { get { return m_path; } set { m_path = value; } }
private Material m_material; //材质
public Material Material { get { return m_material; } set { m_material = value; } }
}
public class ShaderCheckInfo
{
private string m_name = ""; //shader名称
public string Name { get { return m_name; } set { m_name = value; } }
private string m_path = ""; //shader路径
public string Path { get { return m_path; } set { m_path = value; } }
private ulong m_variant_count = 0; //shader变体数量
public ulong VariantCount { get { return m_variant_count; } set { m_variant_count = value; } }
public List
public string GetMaterialDes(List
{
var des = "";
for (int i = 0; i < infos.Count; i++)
{
var info = infos[i];
des = des + " " + "Material Name: " + info.Name + " Path: " + info.Path + "\r\n";
}
return des;
}
public override string ToString()
{
return "Shader: " + Name + " Path: " + Path + " VariantCount: " + VariantCount + "\r\n" + GetMaterialDes(m_mat_info);
}
}
public class ShaderCheckInfoCompare : IComparer
{
public int Compare(ShaderCheckInfo x, ShaderCheckInfo y)
{
if (x.VariantCount > y.VariantCount)
return -1;
return 1;
}
}