写了一个用于搜索项目中某一个shader被绑定到哪些material上,右键点击Project上中任意对象,只有点击到shader文件的时候,SearchShader才会触发。我们把该脚本放在Editor中。
基本思路是:首先在右键点击一个对象,当该对象为Shader文件的时候,SearchShader函数可以响应,然后再一个固定的文件夹中遍历该文件夹中的所有Material对象,然后把这些Material对象的路径存在一个listMaterial中。然后在Unity中调用可视化的EditorUtility.DisplayProgressBar的方法,查看目前搜索的对象,比较这些对象所引用的Shder是否为我们右键点击的那个对象。如果是的话,则把该对象的信息保存在另一个listTargetMaterial中。最后打印通过StreamWriter打印出我们想要的结果
代码如下:
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;
public class SearchShader {
public static string FilePath = "Assets/Materials";
//搜索固定文件夹中的所有Material的路径
public static List<string> listMatrials;
public static List<string> listTargetMaterial;
public static string selectedShaderName;
public static StringBuilder sb;
[MenuItem("Assets/SearchShader", true)]
private static bool OptionSelectAvailable()
{
if(Selection.activeObject == null)
{
return false;
}
return Selection.activeObject.GetType() == typeof(Shader);
}
[MenuItem("Assets/SearchShader")]
private static void SearchConstantShader()
{
Debug.Log("当前选中的Shader名字:" + Selection.activeObject.name);
sb = new StringBuilder();
selectedShaderName = Selection.activeObject.name;
listMatrials = new List<string>();
listMatrials.Clear();
listTargetMaterial = new List<string>();
listTargetMaterial.Clear();
//项目路径 eg:projectPath = D:Project/Test/Assets
string projectPath = Application.dataPath;
//eg:projectPath = D:Project/Test
projectPath = projectPath.Substring(0, projectPath.IndexOf("Assets"));
try
{
//获取某一文件夹中的所有Matrial的Path信息
GetMaterialsPath(projectPath, FilePath, "Material",ref listMatrials);
}
catch(System.Exception e)
{
Debug.LogError(e);
}
for (int i = 0; i < listMatrials.Count; i++)
{
EditorUtility.DisplayProgressBar("Check Materials", "Current Material :"
+ i + "/" + listMatrials.Count,(float)i/ listMatrials.Count);
try
{
//开始Check
BegainCheckMaterials(listMatrials[i]);
}
catch (System.Exception e)
{
EditorUtility.ClearProgressBar();
Debug.LogError(e);
}
}
PrintToTxt();
EditorUtility.ClearProgressBar();
Debug.Log("Check Success");
}
//获取某一文件夹中的所有Matrial的Path信息
public static void GetMaterialsPath(string projectPath,string targetFilePath,string searchType,ref List<string> array)
{
if (Directory.Exists(targetFilePath))
{
string[] guids;
//搜索
guids = AssetDatabase.FindAssets("t:" + searchType, new[] { targetFilePath });
foreach (string guid in guids)
{
string source = AssetDatabase.GUIDToAssetPath(guid);
listMatrials.Add(source);
}
}
}
//开始检查Material
public static void BegainCheckMaterials(string materialPath)
{
Material mat = AssetDatabase.LoadAssetAtPath<Material>(materialPath);
if (mat.shader.name == selectedShaderName)
{
listTargetMaterial.Add(materialPath);
}
}
public static void PrintToTxt()
{
//加入shader的名字
listTargetMaterial.Add(selectedShaderName);
FileInfo fi = new FileInfo(Application.dataPath + "/Materials.txt");
if (!fi.Exists)
{
fi.CreateText();
}
else
{
StreamWriter sw = new StreamWriter(Application.dataPath + "/Materials.txt");
for (int i = 0; i < listTargetMaterial.Count - 1; i++)
{
sb.Append(listTargetMaterial[i] + "\n");
}
string useNum = string.Format("共有 {0} 个Material用到:{1}", listTargetMaterial.Count - 1, selectedShaderName);
sb.Append(useNum + "\n");
sb.Append("用到的shader名字为:" + selectedShaderName);
sw.Write(sb.ToString());
sw.Flush();
sw.Close();
sw.Dispose();
}
}
}