当前位置: 代码迷 >> 综合 >> 引入材质反向查找预制件工具
  详细解决方案

引入材质反向查找预制件工具

热度:97   发布时间:2023-10-20 15:03:48.0

前几天资源策划找到我,希望可以有一个查看所有Shader引用的资源查找工具,方便之后对资源进行归类整理

Shader被材质引用,预制件中也需要依赖材质进行渲染,这个工具也就提供了多种查找途径

1.根据Shader查找自定义路径下所有的的Material

2.根据Material查找自定义路径下所有的Prefab

3.根据Shader查找自定义路径下所有的Prefab

他们能实现的根本原因就在于Prefab上可以获取到Marterial,Material可以获取到Shader,这种依赖关系就决定可以实现上述需求

 

    /// <summary>
    /// 根据Shader查找Material
    /// </summary>

    public static void SerachMaterialWithShader()
    {
        string shaderPath = string.Empty;
        foreach (UnityEngine.Object obj in Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets))
        {
            shaderPath = AssetDatabase.GetAssetPath(obj);
            Shader shader = AssetDatabase.LoadAssetAtPath(shaderPath, typeof(Shader)) as Shader;
            if (shader != null)
            {
                CheckMaterialWithShader("Assets\\Resources", shader);          
            }
            else
            {
                Debug.LogError("查找失败,请检查Shader文件:" + shaderPath);
                return;
            }
        }
        Debug.Log("------------写入成功-------------");
    }

    /// <summary>
    /// 根据Shader查找预制
    /// </summary>
    public static void SerachPrefabWithShader()
    {
       
        string shaderPath = string.Empty;
        foreach (UnityEngine.Object obj in Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets))
        {
            shaderPath = AssetDatabase.GetAssetPath(obj);
            Shader shader = AssetDatabase.LoadAssetAtPath(shaderPath, typeof(Shader)) as Shader;
            if (shader != null)
            {
                CheckPrefabWithShader("Assets\\Resources", shader);        
            }
            else
            {
                Debug.LogError("查找失败,请检查Shader文件:" + shaderPath);
                return;
            }
        }
        Debug.Log("------------写入成功-------------");
    }

    /// <summary>
    /// 根据材质查找预制
    /// </summary>
    public static void SerachPrefabWithMaterial()
    {
      
        string matpath = string.Empty;
        foreach (UnityEngine.Object obj in Selection.GetFiltered(typeof(UnityEngine.Object), SelectionMode.Assets))
        {
            matpath = AssetDatabase.GetAssetPath(obj);
            Material mat = AssetDatabase.LoadAssetAtPath(matpath, typeof(Material)) as Material;
            if (mat != null)
            {
                
                CheckPrefabWithMaterial("Assets\\Resources", mat); 
            }
            else
            {
                Debug.LogError("查找失败,请检查Material文件:" + matpath);
                return;
            }
        }
        Debug.Log("------------写入成功-------------");
    }


    public static void CheckPrefabWithShader(string prefabPath,Shader shader) 
    {
        List<string> contents = new List<string>();
        contents.Add("--------------------" + shader.name + "文件被以下Prefab引用-------------------------");
        if (Directory.Exists(prefabPath+"/"))
        {
            DirectoryInfo direction = new DirectoryInfo(prefabPath+"/");
            FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
            for (int i = 0; i < files.Length; i++)
            {
                string path = files[i].DirectoryName + "\\" + files[i].Name;
                path = path.Replace(prefabPath, "#");
                string[] path_2 = path.Split('#');
                if (files[i].Name.EndsWith(".prefab"))
                {
                    if (path_2.Length == 2)
                    {
                        string prefab_path = prefabPath + path_2[1];
                        GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefab_path);
                        if (prefab != null)
                        {
                            bool findShader = false;
                            Renderer[] meshs = prefab.GetComponentsInChildren<Renderer>(true);
                            if (meshs != null)
                            {
                                foreach (var m in meshs)
                                {
                                    if (m.sharedMaterials != null)
                                    {
                                        foreach (var mat in m.sharedMaterials)
                                        {
                                            if (mat != null)
                                            {
                                                if (shader.name == mat.shader.name)
                                                {
                                                    findShader = true;
                                                }

                                            }
                                        }

                                    }
                                }
                                if (findShader)
                                {
                                    contents.Add(prefab_path);
                                }
                            }
                        }
                    }
                }
            }
        }
        WriteFile(contents, "CheckReference.txt");
    }

    public static void CheckMaterialWithShader(string matpath, Shader shader)
    {
        List<string> contents = new List<string>();
        contents.Add("--------------------" + shader.name + "文件被以下Material引用-------------------------");
        if (Directory.Exists(matpath + "/"))
        {
            DirectoryInfo direction = new DirectoryInfo(matpath+"/");
            FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
          
            for (int i = 0; i < files.Length; i++)
            {
                string path = files[i].DirectoryName + "\\" + files[i].Name;
                path = path.Replace(matpath, "#");
                string[] path_2 = path.Split('#');
                if (files[i].Name.EndsWith(".mat"))
                {
                    if (path_2.Length == 2)
                    {
                        string material_path = matpath + path_2[1];
                        Material material = AssetDatabase.LoadAssetAtPath(material_path, typeof(Material)) as Material;
                        if (material != null)
                        {
                            if (material.shader.name == shader.name)
                            {
                                contents.Add(material_path);
                            }     
                        }
                    }
                }
            } 
        }
        WriteFile(contents, "CheckReference.txt");
    }

    public static void CheckPrefabWithMaterial(string prefabPath, Material mat)
    {
        List<string> contents = new List<string>();
        contents.Add("--------------------" + mat.name + "文件被以下Prefab引用-------------------------");
        if (Directory.Exists(prefabPath + "/"))
        {
            DirectoryInfo direction = new DirectoryInfo(prefabPath + "/");
            FileInfo[] files = direction.GetFiles("*", SearchOption.AllDirectories);
            for (int i = 0; i < files.Length; i++)
            {
                string path = files[i].DirectoryName + "\\" + files[i].Name;
                path = path.Replace(prefabPath, "#");
                string[] path_2 = path.Split('#');
                if (files[i].Name.EndsWith(".prefab"))
                {
                    if (path_2.Length == 2)
                    {
                        string prefab_path = prefabPath + path_2[1];
                        GameObject prefab = AssetDatabase.LoadAssetAtPath<GameObject>(prefab_path);
                        if (prefab != null)
                        {
                            bool findMat = false;
                            Renderer[] meshs = prefab.GetComponentsInChildren<Renderer>(true);
                            if (meshs != null)
                            {
                                foreach (var m in meshs)
                                {
                                    if (m.sharedMaterials != null)
                                    {
                                        foreach (var mater in m.sharedMaterials)
                                        {
                                            if (mater != null)
                                            {
                                                if (mat.name == mater.name)
                                                {
                                                    findMat = true;
                                                }

                                            }
                                        }

                                    }
                                }
                                if (findMat)
                                {
                                    contents.Add(prefab_path);
                                }
                            }
                        }
                    }
                }
            }
        }

        WriteFile(contents, "CheckReference.txt");
    }

    public static bool WriteFile(List<string> content, string sFile)
    {
        string path = Application.dataPath;
        path = path.Substring(0, path.IndexOf("Assets"));
        sFile = path + "\\" + sFile;
        StreamWriter writer = null;
        try
        {
            writer = new StreamWriter(sFile, true, System.Text.Encoding.GetEncoding("UTF-8"));
            for (int i = 0; i < content.Count; i++)
            {
                writer.WriteLine(content[i]);
            }
            writer.WriteLine("");
            writer.WriteLine("");
            writer.WriteLine("");
        }
        catch (IOException e)
        {
            return false;
        }
        finally
        {
            if (writer != null)
                writer.Close();
        }
        return true;
    }

  相关解决方案