unity——删除fbx 默认材质


删除fbx默认材质:https://www.jianshu.com/p/632869a87848

https://zhuanlan.zhihu.com/p/27271879

 

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity.EditorCoroutines.Editor;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace Assets.Snowstorm.Editor
{
    class CheckOrChangeUnityShader : EditorWindow
    {
        public enum MatType
        {
            Standard = 0,
            ParticleSystem = 1,
            Sprite = 2,
            Normal = 3,
        }

        static CheckOrChangeUnityShader self;
        static Material replacedStandardMat;
        static Material replacedSpriteMat;
        static Material replacedParticleSystemMat;
        static Dictionary<MatType, Material> typeAndMaterial;

        static List<Shader> shadersInProject;
        static List<Material> matsInProject;

        static Dictionary<string, Shader> shaderNameAndShaders;
        static Dictionary<string, List<Material>> shaderNameAndMats;
        static Dictionary<string, List<Material>> wrongShaderNameAndMats;
        static List<string> NotFoundShaderList;

        static List<Material> sameNameMat;
        static List<Material> noEnvenSameNameMat;
        static List<Material> standardMat;

        public static void InitReplacedMats()
        {
            replacedStandardMat = AssetDatabase.LoadAllAssetsAtPath("Assets/Snowstorm/Material/Default_Mat.mat")[0] as Material;
            replacedSpriteMat = AssetDatabase.LoadAllAssetsAtPath("Assets/Snowstorm/Material/Default_Sprite.mat")[0] as Material;
            replacedParticleSystemMat = AssetDatabase.LoadAllAssetsAtPath("Assets/Snowstorm/Material/Default_ParticleSystem.mat")[0] as Material;
            typeAndMaterial = new Dictionary<MatType, Material>();
            typeAndMaterial.Add(MatType.ParticleSystem, replacedParticleSystemMat);
            typeAndMaterial.Add(MatType.Sprite, replacedSpriteMat);
            typeAndMaterial.Add(MatType.Standard, replacedStandardMat);
            typeAndMaterial.Add(MatType.Normal, replacedStandardMat);
            wrongShaderNameAndMats = new Dictionary<string, List<Material>>();

            shadersInProject = new List<Shader>();
            shaderNameAndShaders = new Dictionary<string, Shader>();
            matsInProject = new List<Material>();
            shaderNameAndMats = new Dictionary<string, List<Material>>();
            NotFoundShaderList = new List<string>();
            sameNameMat = new List<Material>();
            noEnvenSameNameMat = new List<Material>();
            standardMat = new List<Material>();
        }

        public static MatType GetReplacedMatType(Material srcMat)
        {
            if (srcMat == null)
            {
                return MatType.Standard;
            }
            else if (srcMat.name.Equals("Default-ParticleSystem")
                || srcMat.shader.name.Equals("Particles/Standard Unlit"))
            {
                return MatType.ParticleSystem;
            }
            else if (srcMat.name.Equals("Sprites-Default")
                || srcMat.shader.name.Equals("Sprites/Default"))
            {
                return MatType.Sprite;
            }
            else if (srcMat.name.Equals("Default-Material")
                || srcMat.shader.name.Equals("Standard"))
            {
                return MatType.Standard;
            }
            return MatType.Normal;
        }

        [MenuItem("Tools/Shader/OptimizeShaders")]
        public static CheckOrChangeUnityShader GetWindow()
        {
            if (self == null)
                self = GetWindow<CheckOrChangeUnityShader>();
            self.Show();
            return self;
        }

        private void OnGUI()
        {
            GUILayout.Label("OptimizeShaders");
            if (GUILayout.Button("Check And Optimize Shaders"))
            {
                InitReplacedMats();

                CheckAndFixAllFbxStandardMat();

                if(OptimizeMat())
                {
                    ChangeSceneObjDefaultMat();

                    FixPrefabStandardShader();

                    ClearShaderData();

                    ExportShaderVariantAndSplit();
                }
                else
                {
                    GUILayout.Button("There is an error, please look at: " + Application.dataPath + "/AllProjectShaders.txt");
                }
            }
        }

        #region fbx
        public static IEnumerator ChangeModelMatExternal(string[] materialGUIDArray)
        {
            GameObject obj = null;
            string path = "";
            for (int i = 0; i < materialGUIDArray.Length; i++)
            {
                path = AssetDatabase.GUIDToAssetPath(materialGUIDArray[i]);
                obj = AssetDatabase.LoadAllAssetsAtPath(path)[0] as GameObject;
                if (null != obj)
                {
                    string assetPath = AssetDatabase.GetAssetPath(obj);
                    ModelImporter importer = AssetImporter.GetAtPath(assetPath) as ModelImporter;
                    if (!(null == importer || (importer.importMaterials && importer.materialLocation == ModelImporterMaterialLocation.External)))
                    {
                        Debug.Log(assetPath);
                        importer.importMaterials = true;
                        importer.materialLocation = ModelImporterMaterialLocation.External;
                        importer.materialName = ModelImporterMaterialName.BasedOnModelNameAndMaterialName;
                        importer.materialSearch = ModelImporterMaterialSearch.Local;
                        importer.SaveAndReimport();
                    }
                }
            }
            yield return null;
        }

        static void CheckAndFixAllFbxStandardMat()
        {
            string[] materialGUIDArray = AssetDatabase.FindAssets("t:model", new string[1] { "Assets" });
            if (materialGUIDArray == null && materialGUIDArray.Length == 0)
            {
                return;
            }
            EditorCoroutineUtility.StartCoroutineOwnerless(ChangeModelMatExternal(materialGUIDArray));
        }
        #endregion

        #region material operation
        static void findAllShadersInProject()
        {
            string[] shaderGUIDArray = AssetDatabase.FindAssets("t:shader", new string[1] { "Assets" });
            shadersInProject.Clear();
            shaderNameAndShaders.Clear();
            Shader shader = null;
            string path = "";
            for (int i = 0; i < shaderGUIDArray.Length; i++)
            {
                path = AssetDatabase.GUIDToAssetPath(shaderGUIDArray[i]);
                shader = AssetDatabase.LoadAllAssetsAtPath(path)[0] as Shader;
                if (shader)
                {
                    shadersInProject.Add(shader);
                    shaderNameAndShaders.Add(shader.name, shader);
                    EditorUtility.DisplayProgressBar("findAllShadersInProject", "Shader -> " + shader.name, i / shaderGUIDArray.Length);
                }
            }
        }

        static void findAllMatsInProject()
        {
            string[] materialGUIDArray = AssetDatabase.FindAssets("t:material", new string[1] { "Assets" });
            matsInProject.Clear();
            Material mat = null;
            string path = "";
            for (int i = 0; i < materialGUIDArray.Length; i++)
            {
                path = AssetDatabase.GUIDToAssetPath(materialGUIDArray[i]);
                mat = AssetDatabase.LoadAllAssetsAtPath(path)[0] as Material;
                if (mat)
                {
                    matsInProject.Add(mat);
                    EditorUtility.DisplayProgressBar("findAllMatsInProject", "Material -> " + mat.name, i / materialGUIDArray.Length);
                }
            }
        }

        [MenuItem("Assets/Shader/AllShaderAndMatInfos")]
        static bool findAllShaderAndItsMat()
        {
            InitReplacedMats();
            if (shadersInProject == null || shadersInProject.Count == 0)
            {
                findAllShadersInProject();
            }
            if (matsInProject == null || matsInProject.Count == 0)
            {
                findAllMatsInProject();
            }

            for (int i = 0; i < matsInProject.Count; i++)
            {
                EditorUtility.DisplayProgressBar("Check material and its shader", "Material -> " + matsInProject[i].name, i / matsInProject.Count);
                
                // 对应的shader不在工程内
                if (!shadersInProject.Contains(matsInProject[i].shader))
                {
                    //所有shader不存在的、对应不上的,有问题的列表  shader和材质列表进行搜集
                    if (wrongShaderNameAndMats.ContainsKey(matsInProject[i].shader.name))
                    {
                        wrongShaderNameAndMats[matsInProject[i].shader.name].Add(matsInProject[i]);
                    }
                    else
                    {
                        List<Material> matList = new List<Material>();
                        matList.Add(matsInProject[i]);
                        wrongShaderNameAndMats.Add(matsInProject[i].shader.name, matList);
                    }

                    //shader不存在,但存在同名的shader
                    if (shaderNameAndShaders.ContainsKey(matsInProject[i].shader.name))
                    {
                        sameNameMat.Add(matsInProject[i]);
                    }
                    else
                    {
                        //同名的都不存在
                        if (!matsInProject[i].shader.name.Equals("Standard"))
                        {
                            noEnvenSameNameMat.Add(matsInProject[i]);
                            NotFoundShaderList.Add(matsInProject[i].name);
                        }
                        else
                        {
                            standardMat.Add(matsInProject[i]);
                        }
                    }
                }
                else
                {
                    if (shaderNameAndMats.ContainsKey(matsInProject[i].shader.name))
                    {
                        shaderNameAndMats[matsInProject[i].shader.name].Add(matsInProject[i]);
                    }
                    else
                    {
                        List<Material> matList = new List<Material>();
                        matList.Add(matsInProject[i]);
                        shaderNameAndMats.Add(matsInProject[i].shader.name, matList);
                    }
                }
            }

            EditorUtility.ClearProgressBar();

            //写文件 文件名为save.text
            //这里的FileMode.create是创建这个文件,如果文件名存在则覆盖重新创建
            FileStream fs = new FileStream(Application.dataPath + "/AllProjectShaders.txt", FileMode.Create);

            byte[] bytesTile = new UTF8Encoding().GetBytes("所有有问题的,shader有同名但对不上的和连同名都没有的: " + "\r\n");
            fs.Write(bytesTile, 0, bytesTile.Length);
            foreach (KeyValuePair<string, List<Material>> shaderAndMat in wrongShaderNameAndMats)
            {
                byte[] bytes = new UTF8Encoding().GetBytes(shaderAndMat.Key + "\r\n");
                fs.Write(bytes, 0, bytes.Length);
                foreach (var item in shaderAndMat.Value)
                {
                    byte[] bytes1 = new UTF8Encoding().GetBytes(item + "\r\n" + "\r\n");
                    fs.Write(bytes1, 0, bytes1.Length);
                }
                byte[] bytes2 = new UTF8Encoding().GetBytes("\r\n" + "\r\n");
                fs.Write(bytes2, 0, bytes2.Length);
            }

            bytesTile = new UTF8Encoding().GetBytes("Same Name Material,所有有同名的 " + "\r\n");
            fs.Write(bytesTile, 0, bytesTile.Length);
            foreach (var item in sameNameMat)
            {
                byte[] bytes1 = new UTF8Encoding().GetBytes(item + "\r\n" + "\r\n");
                fs.Write(bytes1, 0, bytes1.Length);
            }

            bytesTile = new UTF8Encoding().GetBytes("Not Exist even Same Name Material,连同名的都没有的 " + "\r\n");
            fs.Write(bytesTile, 0, bytesTile.Length);

            foreach (var item in noEnvenSameNameMat)
            {
                byte[] bytes1 = new UTF8Encoding().GetBytes(item + "\r\n" + "\r\n");
                fs.Write(bytes1, 0, bytes1.Length);
            }

            bytesTile = new UTF8Encoding().GetBytes("Standard Material,用的标准shader的 " + "\r\n");
            fs.Write(bytesTile, 0, bytesTile.Length);

            foreach (var item in standardMat)
            {
                byte[] bytes1 = new UTF8Encoding().GetBytes(item + "\r\n" + "\r\n");
                fs.Write(bytes1, 0, bytes1.Length);
            }

            //每次读取文件后都要记得关闭文件
            fs.Close();

            if (noEnvenSameNameMat.Count > 0)
            {
                return false;
            }
            return true;
        }

        // 刷所有材质上的标准shader、指认shader
        [MenuItem("Assets/Shader/OptimizeMat")]
        static bool OptimizeMat()
        {
            if (!findAllShaderAndItsMat())
            {
                return false;
            }
            else
            {
                for (int i = 0; i < standardMat.Count; i++)
                {
                    standardMat[i].shader = Shader.Find("Mobile/Diffuse");
                }

                for (int i = 0; i < sameNameMat.Count; i++)
                {
                    standardMat[i].shader = shaderNameAndShaders[standardMat[i].shader.name];
                }

                Debug.Log("Optimize material and shader Success!");
                return true;
            }
        }
        #endregion material operation

        static void ClearShaderData()
        {
            shadersInProject = null;
            matsInProject = null;

            shaderNameAndShaders = null;
            shaderNameAndMats = null;
            wrongShaderNameAndMats = null;

            sameNameMat = null;
            noEnvenSameNameMat = null;
            standardMat = null;

            NotFoundShaderList = null;
        }

        //每个物体的检查和替换代码封装
        private static bool CheckAndReplaceObjectMats(ref GameObject obj)
        {
            MatType type = MatType.Normal;
            Renderer[] allRender = obj.GetComponentsInChildren<Renderer>(true);
            ParticleSystemRenderer[] allParticleSystemRenderers = obj.GetComponentsInChildren<ParticleSystemRenderer>(true);
            bool needSave = false;
            for (int j = 0; j < allRender.Length; j++)
            {
                Material[] srcMats = allRender[j].sharedMaterials;
                bool needSaveMats = false;
                if (srcMats != null)
                {
                    for (int k = 0; k < srcMats.Length; k++)
                    {
                        type = MatType.Normal;
                        if (GetReplacedMatType(srcMats[k]) != MatType.Normal)
                        {
                            needSaveMats = true;
                            needSave = true;
                            srcMats[k] = typeAndMaterial[type];
                        }
                    }
                    if (needSaveMats)
                    {
                        allRender[j].sharedMaterials = srcMats;
                    }
                }

            }

            for (int j = 0; j < allParticleSystemRenderers.Length; j++)
            {
                Material[] srcMats = allParticleSystemRenderers[j].sharedMaterials;
                if (srcMats != null)
                {
                    bool needSaveMats = false;
                    for (int k = 0; k < srcMats.Length; k++)
                    {
                        type = MatType.Normal;
                        if (GetReplacedMatType(srcMats[k]) != MatType.Normal)
                        {
                            needSaveMats = true;
                            needSave = true;
                            srcMats[k] = typeAndMaterial[type];
                        }
                    }
                    if (needSaveMats)
                    {
                        allParticleSystemRenderers[j].sharedMaterials = srcMats;
                    }
                }

                Material trailMat = allParticleSystemRenderers[j].trailMaterial;
                type = MatType.Normal;
                if (GetReplacedMatType(trailMat) != MatType.Normal)
                {
                    needSave = true;
                    allParticleSystemRenderers[j].trailMaterial = typeAndMaterial[type];
                }
            }

            return needSave;
        }

        #region SceneObject
        //所有场景中的所有物体中的内置的几种材质shader替换掉
        static void ChangeSceneObjDefaultMat()
        {
            string headPath = Application.dataPath;
            //eg:D:/Project/Test/
            headPath = headPath.Substring(0, headPath.IndexOf("Assets"));

            List<string> optimizedOriginalScenePaths = new List<string>();
            TextureModifier.AddRootSourcePathToList("Assets/Snowstorm", headPath, "Scene", ref optimizedOriginalScenePaths); ///Env/Scenes

            for (int i = 0; i < optimizedOriginalScenePaths.Count; i++)
            {
                EditorUtility.DisplayProgressBar("ChangeSceneObjDefaultMat", "Scene -> " + optimizedOriginalScenePaths[i], i / optimizedOriginalScenePaths.Count);
                EditorSceneManager.OpenScene(optimizedOriginalScenePaths[i], OpenSceneMode.Single);
                GameObject[] gameObject = UnityEngine.Object.FindObjectsOfType<GameObject>();
                bool needSave = false;
                for (int k = 0; k < gameObject.Length; k++)
                {
                    needSave = CheckAndReplaceObjectMats(ref gameObject[k]);
                }

                if (needSave)
                {
                    EditorSceneManager.SaveScene(SceneManager.GetActiveScene());
                }
            }
            EditorUtility.ClearProgressBar();
        }
        #endregion

        #region prefabFix
        // 所有prefab检查修改
        [MenuItem("Assets/Shader/FixPrefabStandardShader")]
        static void FixPrefabStandardShader()
        {
            InitReplacedMats();
            Scene newScene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
            Lightmapping.giWorkflowMode = Lightmapping.GIWorkflowMode.OnDemand;

            Dictionary<string, bool> wrongStandardPrefabList = new Dictionary<string, bool>();
            Dictionary<string, bool> wrongSpritePrefabList = new Dictionary<string, bool>();
            Dictionary<string, bool> wrongParticleSystemPrefabList = new Dictionary<string, bool>();

            Dictionary<MatType, Dictionary<string, bool>> wrongPrefabList = new Dictionary<MatType, Dictionary<string, bool>>();
            wrongPrefabList.Add(MatType.ParticleSystem, wrongParticleSystemPrefabList);
            wrongPrefabList.Add(MatType.Sprite, wrongSpritePrefabList);
            wrongPrefabList.Add(MatType.Standard, wrongStandardPrefabList);

            bool needSave = false;

            List<Material> ms = new List<Material>();
            GameObject prefabObj = null;

            string[] prefabGUIDArray = AssetDatabase.FindAssets("t:prefab", new string[1] { "Assets" });
            for (int i = 0; i < prefabGUIDArray.Length; i++)
            {
                string path = AssetDatabase.GUIDToAssetPath(prefabGUIDArray[i]);
                var asset = AssetDatabase.LoadAssetAtPath<GameObject>(path);
                if (asset == null)
                {
                    continue;
                }

                prefabObj = PrefabUtility.InstantiatePrefab(asset, SceneManager.GetActiveScene()) as GameObject;
                EditorUtility.DisplayProgressBar("FixPrefabStandardShader", "Prefab -> " + prefabObj.name, i / prefabGUIDArray.Length);

                needSave = CheckAndReplaceObjectMats(ref prefabObj);

                if (needSave)
                {
                    PrefabUtility.SaveAsPrefabAsset(prefabObj, path);
                }
            }
            EditorUtility.ClearProgressBar();
            Scene scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);

        }
        #endregion

        //#region checkAgain
        //static void CheckAgain()
        //{
        //    var dict = new Dictionary<string, bool>();

        //    foreach (var assetBundleName in AssetDatabase.GetAllAssetBundleNames())
        //    {
        //        string[] assetPaths = AssetDatabase.GetAssetPathsFromAssetBundle(assetBundleName);
        //        foreach (var dependency in AssetDatabase.GetDependencies(assetPaths, true))
        //        {
        //            if (!dict.ContainsKey(dependency))
        //            {
        //                Debug.Log(dependency + "        111111111         " + assetPaths);
        //                dict.Add(dependency, true);
        //            }
        //        }
        //    }

        //    var di = new DirectoryInfo("Assets");
        //    foreach (var fi in di.GetFiles("*", SearchOption.AllDirectories))
        //    {
        //        if (fi.Extension == ".meta")
        //        {
        //            continue;
        //        }

        //        string assetPath = fi.FullName.Replace(Application.dataPath, "Assets");
        //        foreach (var dependency in AssetDatabase.GetDependencies(assetPath, true))
        //        {
        //            if (!dict.ContainsKey(dependency))
        //            {
        //                Debug.Log(dependency + "       2222222222         " + assetPath);
        //                dict.Add(dependency, true);
        //            }
        //        }
        //    }

        //    string[] scenes = (from scene in EditorBuildSettings.scenes
        //                       where scene.enabled
        //                       select scene.path).ToArray();
        //    foreach (var dependency in AssetDatabase.GetDependencies(scenes, true))
        //    {
        //        if (!dict.ContainsKey(dependency))
        //        {
        //            Debug.Log(dependency + "  33333333333         ");
        //            dict.Add(dependency, true);
        //        }
        //    }

        //    var materials = new List<Material>();
        //    var shaderDict = new Dictionary<Shader, List<Material>>();
        //    foreach (var assetPath in dict.Keys)
        //    {
        //        var material = AssetDatabase.LoadAssetAtPath<Material>(assetPath);
        //        if (material != null)
        //        {
        //            if (material.shader != null)
        //            {
        //                if (shadersInProject.Contains(material.shader))
        //                {
        //                    continue;
        //                }
        //                else
        //                {
        //                    if(!noEnvenSameNameMat.Contains(material))
        //                    {
        //                        noEnvenSameNameMat.Add(material);
        //                        NotFoundShaderList.Add(material.name);
        //                    }
        //                }
        //            }

        //        }
        //    }

        //    FileStream fs = new FileStream(Application.dataPath + "/NotFoundShader.txt", FileMode.Create);
        //    //存储时时二进制,所以这里需要把我们的字符串转成二进制


        //    byte[] bytesElement = new UTF8Encoding().GetBytes("没找到的shader: " + "\r\n");
        //    fs.Write(bytesElement, 0, bytesElement.Length);

        //    foreach (var item in NotFoundShaderList)
        //    {
        //        byte[] bytes = new UTF8Encoding().GetBytes(item + "\r\n");
        //        fs.Write(bytes, 0, bytes.Length);

        //    }

        //    bytesElement = new UTF8Encoding().GetBytes("没找到shader的材质: " + "\r\n");
        //    fs.Write(bytesElement, 0, bytesElement.Length);

        //    foreach (var item in noEnvenSameNameMat)
        //    {
        //        byte[] bytes = new UTF8Encoding().GetBytes(item + "\r\n");
        //        fs.Write(bytes, 0, bytes.Length);

        //    }

        //    byte[] bytesEnd = new UTF8Encoding().GetBytes("\r\n");
        //    fs.Write(bytesEnd, 0, bytesEnd.Length);
        //}
        //#endregion

        #region ExportAndSplit
        static void ExportShaderVariantAndSplit()
        {
            Debug.Log("ExportShaderVariantAndSplit +++                ------------");
            ShaderVariantCollectionExporter.Export();

            ShaderVariantCollection svc = AssetDatabase.LoadAllAssetsAtPath("Assets/Snowstorm/Shader/SVC_T.shadervariants")[0] as ShaderVariantCollection;

            if (Directory.Exists(Application.dataPath + "/Snowstorm/Shader/ShaderVariantBank"))
            {
                Directory.Delete(Application.dataPath + "/Snowstorm/Shader/ShaderVariantBank", true);
                Debug.Log("删除shaderVariantBank文件夹");
            }
            if (!Directory.Exists(Application.dataPath + "/Snowstorm/Shader/ShaderVariants"))
            {
                Directory.CreateDirectory(Application.dataPath + "/Snowstorm/Shader/ShaderVariants");
                Debug.Log("删除shaderVariants文件夹");
            }

            SplitShaderVariantsCollectionEditor.SplitShaderVariantCollection(svc);
            Debug.Log("All Succeed, please look at txt !!");
        }
        #endregion
    }
}

  输出shader变体

using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Diagnostics;
using System.Linq;
using UnityEngine;
using UnityEditor;
using UnityEditor.SceneManagement;
using Debug = UnityEngine.Debug;
using System.Text;

[InitializeOnLoad]
public static class ShaderVariantCollectionExporter
{
    private static bool _isStarted;
    private static readonly Stopwatch _elapsedTime = new Stopwatch();

    private const string ShaderVariantCollectionPath = "Assets/Snowstorm/Shader/SVC_T.shadervariants";
    private const int WaitTimeBeforeSave = 1000;
    private const string CollectionDirectoryPath = "Assets";
    
    [MenuItem("Tools/Shader/Export ShaderVariantCollection")]
    public static void Export()
    {
        var dict = new Dictionary<string, bool>();

        foreach (var assetBundleName in AssetDatabase.GetAllAssetBundleNames())
        {
            string[] assetPaths = AssetDatabase.GetAssetPathsFromAssetBundle(assetBundleName);
            foreach (var dependency in AssetDatabase.GetDependencies(assetPaths, true))
            {
                if (!dict.ContainsKey(dependency))
                {
                    Debug.Log(dependency + "        111111111         " + assetPaths);
                    dict.Add(dependency, true);
                }
            }
        }

        var di = new DirectoryInfo(CollectionDirectoryPath);
        foreach (var fi in di.GetFiles("*", SearchOption.AllDirectories))
        {
            if (fi.Extension == ".meta")
            {
                continue;
            }

            string assetPath = fi.FullName.Replace(Application.dataPath, "Assets");
            foreach (var dependency in AssetDatabase.GetDependencies(assetPath, true))
            {
                if (!dict.ContainsKey(dependency))
                {
                    Debug.Log(dependency + "       2222222222         " + assetPath);
                    dict.Add(dependency, true);
                }
            }
        }

        string[] scenes = (from scene in EditorBuildSettings.scenes
            where scene.enabled
            select scene.path).ToArray();
        foreach (var dependency in AssetDatabase.GetDependencies(scenes, true))
        {
            if (!dict.ContainsKey(dependency))
            {
                Debug.Log(dependency + "  33333333333         " );
                dict.Add(dependency, true);
            }
        }

        var materials = new List<Material>();
        var shaderDict = new Dictionary<Shader, List<Material>>();
        foreach (var assetPath in dict.Keys)
        {
            var material = AssetDatabase.LoadAssetAtPath<Material>(assetPath);
            if (material != null)
            {
                if (material.shader != null)
                {
                    if (!shaderDict.ContainsKey(material.shader))
                    {
                        shaderDict.Add(material.shader, new List<Material>());
                    }

                    if (!shaderDict[material.shader].Contains(material))
                    {
                        shaderDict[material.shader].Add(material);
                    }
                }

                if (!materials.Contains(material))
                {
                    materials.Add(material);
                }
            }
        }

        List<Shader> shadersInProject = new List<Shader>();
        string[] shaderGUIDArray = AssetDatabase.FindAssets("t:shader", new string[1] { "Assets" });
        Shader shader = null;
        string path = "";
        for (int i = 0; i < shaderGUIDArray.Length; i++)
        {
            path = AssetDatabase.GUIDToAssetPath(shaderGUIDArray[i]);
            shader = AssetDatabase.LoadAllAssetsAtPath(path)[0] as Shader;
            if (shader)
            {
                shadersInProject.Add(shader);
                EditorUtility.DisplayProgressBar("ShaderVariantCollectionExporter    findAllShadersInProject", "Shader -> " + shader.name, i / shaderGUIDArray.Length);
            }
        }
        EditorUtility.ClearProgressBar();

        Dictionary<Shader, List<Material>> notProjectShader = new Dictionary<Shader, List<Material>>();
        foreach(KeyValuePair<Shader, List<Material>> item in shaderDict)
        {
            if(!shadersInProject.Contains(item.Key))
            {
                notProjectShader.Add(item.Key, item.Value);
            }
        }

        FileStream fs = new FileStream(Application.dataPath + "/DependencyShader.txt", FileMode.Create);
        //存储时时二进制,所以这里需要把我们的字符串转成二进制
        foreach (KeyValuePair<Shader, List<Material>> item in shaderDict)
        {
            byte[] bytes = new UTF8Encoding().GetBytes(item.Key + "\r\n");
            fs.Write(bytes, 0, bytes.Length);
            foreach (var mat in item.Value)
            {
                byte[] bytesElement = new UTF8Encoding().GetBytes(AssetDatabase.GetAssetPath(mat) + "\r\n");
                fs.Write(bytesElement, 0, bytesElement.Length);
            }
            byte[] bytesEnd = new UTF8Encoding().GetBytes("\r\n");
            fs.Write(bytesEnd, 0, bytesEnd.Length);
        }

        byte[] bytesTitle = new UTF8Encoding().GetBytes("not in project shaders         \r\n");
        fs.Write(bytesTitle, 0, bytesTitle.Length);

        foreach (KeyValuePair<Shader, List<Material>> item in notProjectShader)
        {
            byte[] bytes = new UTF8Encoding().GetBytes(item.Key + "\r\n");
            fs.Write(bytes, 0, bytes.Length);
            foreach (var mat in item.Value)
            {
                byte[] bytesElement = new UTF8Encoding().GetBytes(AssetDatabase.GetAssetPath(mat) + "\r\n");
                fs.Write(bytesElement, 0, bytesElement.Length);
            }
            byte[] bytesEnd = new UTF8Encoding().GetBytes("\r\n");
            fs.Write(bytesEnd, 0, bytesEnd.Length);
        }

        //每次读取文件后都要记得关闭文件
        fs.Close();
        fs = null;


        ProcessMaterials(materials);

        var sb = new System.Text.StringBuilder();
        foreach (var kvp in shaderDict)
        {
            sb.AppendLine(kvp.Key + " " + kvp.Value.Count + " times");

            if (kvp.Value.Count <= 5)
            {
                Debug.LogWarning("Shader: " + kvp.Key.name, kvp.Key);

                foreach (var m in kvp.Value)
                {
                    Debug.Log(AssetDatabase.GetAssetPath(m), m);
                }
            }
        }

        Debug.Log(sb.ToString());
    }

    static ShaderVariantCollectionExporter()
    {
        EditorApplication.update += EditorUpdate;
    }

    private static void EditorUpdate()
    {
        if (_isStarted && _elapsedTime.ElapsedMilliseconds >= WaitTimeBeforeSave)
        {
            Debug.Log(InvokeInternalStaticMethod(typeof(ShaderUtil),
                "GetCurrentShaderVariantCollectionVariantCount"));
            _elapsedTime.Stop();
            _elapsedTime.Reset();
            _isStarted = false;
            EditorApplication.isPlaying = false;
            InvokeInternalStaticMethod(typeof(ShaderUtil), "SaveCurrentShaderVariantCollection",
                ShaderVariantCollectionPath);
            Debug.Log(
                InvokeInternalStaticMethod(typeof(ShaderUtil), "GetCurrentShaderVariantCollectionShaderCount"));
            
        }
    }

    private static void ProcessMaterials(List<Material> materials)
    {
        EditorSceneManager.NewScene(NewSceneSetup.DefaultGameObjects);
        InvokeInternalStaticMethod(typeof(ShaderUtil), "ClearCurrentShaderVariantCollection");
        Debug.Log(InvokeInternalStaticMethod(typeof(ShaderUtil), "GetCurrentShaderVariantCollectionShaderCount"));

        int totalMaterials = materials.Count;

        var camera = Camera.main;
        if (camera == null)
        {
            Debug.LogError("Main Camera didn't exist");
            return;
        }

        float aspect = camera.aspect;

        float height = Mathf.Sqrt(totalMaterials / aspect) + 1;
        float width = Mathf.Sqrt(totalMaterials / aspect) * aspect + 1;

        float halfHeight = Mathf.CeilToInt(height / 2f);
        float halfWidth = Mathf.CeilToInt(width / 2f);

        camera.orthographic = true;
        camera.orthographicSize = halfHeight;
        camera.transform.position = new Vector3(0f, 0f, -10f);

        Selection.activeGameObject = camera.gameObject;
        EditorApplication.ExecuteMenuItem("GameObject/Align View to Selected");

        int xMax = (int) (width - 1);

        int x = 0;
        int y = 0;

        for (int i = 0; i < materials.Count; i++)
        {
            var material = materials[i];

            var position = new Vector3(x - halfWidth + 1f, y - halfHeight + 1f, 0f);
            CreateSphere(material, position, x, y, i);

            if (x == xMax)
            {
                x = 0;
                y++;
            }
            else
            {
                x++;
            }
        }

        _elapsedTime.Stop();
        _elapsedTime.Reset();
        _elapsedTime.Start();
        _isStarted = true;
    }

    private static void CreateSphere(Material material, Vector3 position, int x, int y, int index)
    {
        var go = GameObject.CreatePrimitive(PrimitiveType.Sphere);
        go.GetComponent<Renderer>().material = material;
        go.transform.position = position;
        go.name = string.Format("Sphere_{0}|{1}_{2}|{3}", index, x, y, material.name);
    }

    private static object InvokeInternalStaticMethod(System.Type type, string method, params object[] parameters)
    {
        var methodInfo = type.GetMethod(method, BindingFlags.NonPublic | BindingFlags.Static);
        if (methodInfo == null)
        {
            Debug.LogError(string.Format("{0} method didn't exist", method));
            return null;
        }

        return methodInfo.Invoke(null, parameters);
    }
}

  Split shader变体

using System;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEngine;

public class SplitShaderVariantsCollectionEditor : EditorWindow
{
    static SplitShaderVariantsCollectionEditor _self;

    private ShaderVariantCollection _svc;

    private static string _shaderVariantBankFolder = "Assets/Snowstorm/Shader/ShaderVariantBank";

    [MenuItem("Tools/Shader/SplitShaderVariantsCollectionEditor")]
    public static SplitShaderVariantsCollectionEditor GetWindow()
    {
        if (_self == null)
            _self = GetWindow<SplitShaderVariantsCollectionEditor>();
        _self.Show();
        return _self;
    }

    private void OnGUI()
    {
        GUILayout.Label("Split ShaderVariantCollection");
        var tempSVC =
            EditorGUILayout.ObjectField(_svc, typeof(ShaderVariantCollection), false) as ShaderVariantCollection;
        if (tempSVC != _svc)
        {
            _svc = tempSVC;
        }

        if (_svc != null)
        {
            if (GUILayout.Button("Split SVC"))
            {
                SplitShaderVariantCollection(_svc);
            }
        }
    }

    public static void SplitShaderVariantCollection(ShaderVariantCollection svc)
    {
        try
        {
            string outPath =
                Path.Combine(Application.dataPath.Substring(0, Application.dataPath.LastIndexOf("/Assets")),
                    _shaderVariantBankFolder);
            if (!Directory.Exists(outPath)) Directory.CreateDirectory(outPath);
            var svcPath = Path.Combine(Path.GetDirectoryName(AssetDatabase.GetAssetPath(svc)),
                "ShaderVariants");
            if (!Directory.Exists(svcPath)) Directory.CreateDirectory(svcPath);
            var serializedObject = new SerializedObject(svc);
            var m_Shaders = serializedObject.FindProperty("m_Shaders");
            ShaderVariantBank shaderVariantBank = ScriptableObject.CreateInstance<ShaderVariantBank>();
            if (m_Shaders != null)
            {
                StringBuilder sb = new StringBuilder();
                
                for (var i = 0; i < m_Shaders.arraySize; ++i)
                {
                    var entryProp = m_Shaders.GetArrayElementAtIndex(i);
                    var shader = (Shader) entryProp.FindPropertyRelative("first").objectReferenceValue;
                    if (shader != null)
                    {
                        EditorUtility.DisplayProgressBar("Spliting SVC", "Shader -> " + shader.name,
                            (i + 1) * 1.0f / m_Shaders.arraySize);
                        // Variants for this shader
                        var variantsProp = entryProp.FindPropertyRelative("second.variants");
                        for (var j = 0; j < variantsProp.arraySize; ++j)
                        {

                            sb.Clear();
                            var newSVC = new ShaderVariantCollection();

                            var prop = variantsProp.GetArrayElementAtIndex(j);
                            var keywords = prop.FindPropertyRelative("keywords").stringValue;
                            string[] keywordsArr = null;
                            
                            if (!string.IsNullOrEmpty(keywords))
                            {
                                keywordsArr = keywords.Split(' ');
                            }
                            
                            var passType =
                                (UnityEngine.Rendering.PassType) prop.FindPropertyRelative("passType").intValue;
                            
                            newSVC.Add(new ShaderVariantCollection.ShaderVariant(shader, passType, keywordsArr));
                            
                            var path = Path.Combine(Path.GetDirectoryName(AssetDatabase.GetAssetPath(svc)),
                                "ShaderVariants");
                            
                            var filename = sb.Append(shader.name.Replace('/', '_').Replace(' ', '_')).Append("_").Append(keywords)
                                .Append(".shadervariants");
                            
                            shaderVariantBank.AddShaderVariantName(Path.Combine("Shader/ShaderVariants", filename.ToString()));
                            //shaderVariantBank.AddShaderVariantCollection(newSVC);
                            Debug.Log(string.Format("{0}_{1}", shader.name, keywords));
                            var output = Path.Combine(path, filename.ToString());
                            AssetDatabase.CreateAsset(newSVC, output);
                        }
                    }
                    else
                    {
                        Debug.LogWarning("has missing shader.");
                    }
                }
                
                AssetDatabase.Refresh();

                AssetDatabase.CreateAsset(shaderVariantBank,
                    Path.Combine(_shaderVariantBankFolder, "ShaderVariantBank") + ".asset");

                EditorUtility.ClearProgressBar();
            }
        }
        catch (Exception e)
        {
            EditorUtility.DisplayDialog("错误", e.ToString(), "确定");
            EditorUtility.ClearProgressBar();
            throw;
        }
    }
}

  CheckOrChangeUnityShader.cs

using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Unity.EditorCoroutines.Editor;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;
using UnityEngine.SceneManagement;

namespace Assets.Snowstorm.Editor
{
    class CheckOrChangeUnityShader : EditorWindow
    {
        public enum MatType
        {
            Standard = 0,
            ParticleSystem = 1,
            Sprite = 2,
            Normal = 3,
        }

        static CheckOrChangeUnityShader self;
        static Material replacedStandardMat;
        static Material replacedSpriteMat;
        static Material replacedParticleSystemMat;
        static Dictionary<MatType, Material> typeAndMaterial;

        static List<Shader> shadersInProject;
        static List<Material> matsInProject;

        static Dictionary<string, Shader> shaderNameAndShaders;
        static Dictionary<string, List<Material>> shaderNameAndMats;
        static Dictionary<string, List<Material>> wrongShaderNameAndMats;
        static List<string> NotFoundShaderList;

        static List<Material> sameNameMat;
        static List<Material> noEnvenSameNameMat;
        static List<Material> standardMat;

        public static void InitReplacedMats()
        {
            replacedStandardMat = AssetDatabase.LoadAllAssetsAtPath("Assets/Snowstorm/Material/Default_Mat.mat")[0] as Material;
            replacedSpriteMat = AssetDatabase.LoadAllAssetsAtPath("Assets/Snowstorm/Material/Default_Sprite.mat")[0] as Material;
            replacedParticleSystemMat = AssetDatabase.LoadAllAssetsAtPath("Assets/Snowstorm/Material/Default_ParticleSystem.mat")[0] as Material;
            typeAndMaterial = new Dictionary<MatType, Material>();
            typeAndMaterial.Add(MatType.ParticleSystem, replacedParticleSystemMat);
            typeAndMaterial.Add(MatType.Sprite, replacedSpriteMat);
            typeAndMaterial.Add(MatType.Standard, replacedStandardMat);
            typeAndMaterial.Add(MatType.Normal, replacedStandardMat);
            wrongShaderNameAndMats = new Dictionary<string, List<Material>>();

            shadersInProject = new List<Shader>();
            shaderNameAndShaders = new Dictionary<string, Shader>();
            matsInProject = new List<Material>();
            shaderNameAndMats = new Dictionary<string, List<Material>>();
            NotFoundShaderList = new List<string>();
            sameNameMat = new List<Material>();
            noEnvenSameNameMat = new List<Material>();
            standardMat = new List<Material>();
        }

        public static MatType GetReplacedMatType(Material srcMat)
        {
            if (srcMat == null)
            {
                return MatType.Standard;
            }
            else if (srcMat.name.Equals("Default-ParticleSystem")
                || srcMat.shader.name.Equals("Particles/Standard Unlit"))
            {
                return MatType.ParticleSystem;
            }
            else if (srcMat.name.Equals("Sprites-Default")
                || srcMat.shader.name.Equals("Sprites/Default"))
            {
                return MatType.Sprite;
            }
            else if (srcMat.name.Equals("Default-Material")
                || srcMat.shader.name.Equals("Standard"))
            {
                return MatType.Standard;
            }
            return MatType.Normal;
        }

        [MenuItem("Tools/Shader/OptimizeShaders")]
        public static CheckOrChangeUnityShader GetWindow()
        {
            if (self == null)
                self = GetWindow<CheckOrChangeUnityShader>();
            self.Show();
            return self;
        }

        private void OnGUI()
        {
            GUILayout.Label("OptimizeShaders");
            if (GUILayout.Button("Check And Optimize Shaders"))
            {
                InitReplacedMats();

                CheckAndFixAllFbxStandardMat();

                if(OptimizeMat())
                {
                    ChangeSceneObjDefaultMat();

                    FixPrefabStandardShader();

                    ClearShaderData();

                    ExportShaderVariantAndSplit();
                }
                else
                {
                    GUILayout.Button("There is an error, please look at: " + Application.dataPath + "/AllProjectShaders.txt");
                }
            }
        }

        #region fbx
        public static IEnumerator ChangeModelMatExternal(string[] materialGUIDArray)
        {
            GameObject obj = null;
            string path = "";
            for (int i = 0; i < materialGUIDArray.Length; i++)
            {
                path = AssetDatabase.GUIDToAssetPath(materialGUIDArray[i]);
                obj = AssetDatabase.LoadAllAssetsAtPath(path)[0] as GameObject;
                if (null != obj)
                {
                    string assetPath = AssetDatabase.GetAssetPath(obj);
                    ModelImporter importer = AssetImporter.GetAtPath(assetPath) as ModelImporter;
                    if (!(null == importer || (importer.importMaterials && importer.materialLocation == ModelImporterMaterialLocation.External)))
                    {
                        Debug.Log(assetPath);
                        importer.importMaterials = true;
                        importer.materialLocation = ModelImporterMaterialLocation.External;
                        importer.materialName = ModelImporterMaterialName.BasedOnModelNameAndMaterialName;
                        importer.materialSearch = ModelImporterMaterialSearch.Local;
                        importer.SaveAndReimport();
                    }
                }
            }
            yield return null;
        }

        static void CheckAndFixAllFbxStandardMat()
        {
            string[] materialGUIDArray = AssetDatabase.FindAssets("t:model", new string[1] { "Assets" });
            if (materialGUIDArray == null && materialGUIDArray.Length == 0)
            {
                return;
            }
            EditorCoroutineUtility.StartCoroutineOwnerless(ChangeModelMatExternal(materialGUIDArray));
        }
        #endregion

        #region material operation
        static void findAllShadersInProject()
        {
            string[] shaderGUIDArray = AssetDatabase.FindAssets("t:shader", new string[1] { "Assets" });
            shadersInProject.Clear();
            shaderNameAndShaders.Clear();
            Shader shader = null;
            string path = "";
            for (int i = 0; i < shaderGUIDArray.Length; i++)
            {
                path = AssetDatabase.GUIDToAssetPath(shaderGUIDArray[i]);
                shader = AssetDatabase.LoadAllAssetsAtPath(path)[0] as Shader;
                if (shader)
                {
                    shadersInProject.Add(shader);
                    shaderNameAndShaders.Add(shader.name, shader);
                    EditorUtility.DisplayProgressBar("findAllShadersInProject", "Shader -> " + shader.name, i / shaderGUIDArray.Length);
                }
            }
        }

        static void findAllMatsInProject()
        {
            string[] materialGUIDArray = AssetDatabase.FindAssets("t:material", new string[1] { "Assets" });
            matsInProject.Clear();
            Material mat = null;
            string path = "";
            for (int i = 0; i < materialGUIDArray.Length; i++)
            {
                path = AssetDatabase.GUIDToAssetPath(materialGUIDArray[i]);
                mat = AssetDatabase.LoadAllAssetsAtPath(path)[0] as Material;
                if (mat)
                {
                    matsInProject.Add(mat);
                    EditorUtility.DisplayProgressBar("findAllMatsInProject", "Material -> " + mat.name, i / materialGUIDArray.Length);
                }
            }
        }

        [MenuItem("Assets/Shader/AllShaderAndMatInfos")]
        static bool findAllShaderAndItsMat()
        {
            InitReplacedMats();
            if (shadersInProject == null || shadersInProject.Count == 0)
            {
                findAllShadersInProject();
            }
            if (matsInProject == null || matsInProject.Count == 0)
            {
                findAllMatsInProject();
            }

            for (int i = 0; i < matsInProject.Count; i++)
            {
                EditorUtility.DisplayProgressBar("Check material and its shader", "Material -> " + matsInProject[i].name, i / matsInProject.Count);
                
                // 对应的shader不在工程内
                if (!shadersInProject.Contains(matsInProject[i].shader))
                {
                    //所有shader不存在的、对应不上的,有问题的列表  shader和材质列表进行搜集
                    if (wrongShaderNameAndMats.ContainsKey(matsInProject[i].shader.name))
                    {
                        wrongShaderNameAndMats[matsInProject[i].shader.name].Add(matsInProject[i]);
                    }
                    else
                    {
                        List<Material> matList = new List<Material>();
                        matList.Add(matsInProject[i]);
                        wrongShaderNameAndMats.Add(matsInProject[i].shader.name, matList);
                    }

                    //shader不存在,但存在同名的shader
                    if (shaderNameAndShaders.ContainsKey(matsInProject[i].shader.name))
                    {
                        sameNameMat.Add(matsInProject[i]);
                    }
                    else
                    {
                        //同名的都不存在
                        if (!matsInProject[i].shader.name.Equals("Standard"))
                        {
                            noEnvenSameNameMat.Add(matsInProject[i]);
                            NotFoundShaderList.Add(matsInProject[i].name);
                        }
                        else
                        {
                            standardMat.Add(matsInProject[i]);
                        }
                    }
                }
                else
                {
                    if (shaderNameAndMats.ContainsKey(matsInProject[i].shader.name))
                    {
                        shaderNameAndMats[matsInProject[i].shader.name].Add(matsInProject[i]);
                    }
                    else
                    {
                        List<Material> matList = new List<Material>();
                        matList.Add(matsInProject[i]);
                        shaderNameAndMats.Add(matsInProject[i].shader.name, matList);
                    }
                }
            }

            EditorUtility.ClearProgressBar();

            //写文件 文件名为save.text
            //这里的FileMode.create是创建这个文件,如果文件名存在则覆盖重新创建
            FileStream fs = new FileStream(Application.dataPath + "/AllProjectShaders.txt", FileMode.Create);

            byte[] bytesTile = new UTF8Encoding().GetBytes("所有有问题的,shader有同名但对不上的和连同名都没有的: " + "\r\n");
            fs.Write(bytesTile, 0, bytesTile.Length);
            foreach (KeyValuePair<string, List<Material>> shaderAndMat in wrongShaderNameAndMats)
            {
                byte[] bytes = new UTF8Encoding().GetBytes(shaderAndMat.Key + "\r\n");
                fs.Write(bytes, 0, bytes.Length);
                foreach (var item in shaderAndMat.Value)
                {
                    byte[] bytes1 = new UTF8Encoding().GetBytes(item + "\r\n" + "\r\n");
                    fs.Write(bytes1, 0, bytes1.Length);
                }
                byte[] bytes2 = new UTF8Encoding().GetBytes("\r\n" + "\r\n");
                fs.Write(bytes2, 0, bytes2.Length);
            }

            bytesTile = new UTF8Encoding().GetBytes("Same Name Material,所有有同名的 " + "\r\n");
            fs.Write(bytesTile, 0, bytesTile.Length);
            foreach (var item in sameNameMat)
            {
                byte[] bytes1 = new UTF8Encoding().GetBytes(item + "\r\n" + "\r\n");
                fs.Write(bytes1, 0, bytes1.Length);
            }

            bytesTile = new UTF8Encoding().GetBytes("Not Exist even Same Name Material,连同名的都没有的 " + "\r\n");
            fs.Write(bytesTile, 0, bytesTile.Length);

            foreach (var item in noEnvenSameNameMat)
            {
                byte[] bytes1 = new UTF8Encoding().GetBytes(item + "\r\n" + "\r\n");
                fs.Write(bytes1, 0, bytes1.Length);
            }

            bytesTile = new UTF8Encoding().GetBytes("Standard Material,用的标准shader的 " + "\r\n");
            fs.Write(bytesTile, 0, bytesTile.Length);

            foreach (var item in standardMat)
            {
                byte[] bytes1 = new UTF8Encoding().GetBytes(item + "\r\n" + "\r\n");
                fs.Write(bytes1, 0, bytes1.Length);
            }

            //每次读取文件后都要记得关闭文件
            fs.Close();

            if (noEnvenSameNameMat.Count > 0)
            {
                return false;
            }
            return true;
        }

        // 刷所有材质上的标准shader、指认shader
        [MenuItem("Assets/Shader/OptimizeMat")]
        static bool OptimizeMat()
        {
            if (!findAllShaderAndItsMat())
            {
                return false;
            }
            else
            {
                for (int i = 0; i < standardMat.Count; i++)
                {
                    standardMat[i].shader = Shader.Find("Mobile/Diffuse");
                }

                for (int i = 0; i < sameNameMat.Count; i++)
                {
                    standardMat[i].shader = shaderNameAndShaders[standardMat[i].shader.name];
                }

                Debug.Log("Optimize material and shader Success!");
                return true;
            }
        }
        #endregion material operation

        static void ClearShaderData()
        {
            shadersInProject = null;
            matsInProject = null;

            shaderNameAndShaders = null;
            shaderNameAndMats = null;
            wrongShaderNameAndMats = null;

            sameNameMat = null;
            noEnvenSameNameMat = null;
            standardMat = null;

            NotFoundShaderList = null;
        }

        //每个物体的检查和替换代码封装
        private static bool CheckAndReplaceObjectMats(ref GameObject obj)
        {
            MatType type = MatType.Normal;
            Renderer[] allRender = obj.GetComponentsInChildren<Renderer>(true);
            ParticleSystemRenderer[] allParticleSystemRenderers = obj.GetComponentsInChildren<ParticleSystemRenderer>(true);
            bool needSave = false;
            for (int j = 0; j < allRender.Length; j++)
            {
                Material[] srcMats = allRender[j].sharedMaterials;
                bool needSaveMats = false;
                if (srcMats != null)
                {
                    for (int k = 0; k < srcMats.Length; k++)
                    {
                        type = MatType.Normal;
                        if (GetReplacedMatType(srcMats[k]) != MatType.Normal)
                        {
                            needSaveMats = true;
                            needSave = true;
                            srcMats[k] = typeAndMaterial[type];
                        }
                    }
                    if (needSaveMats)
                    {
                        allRender[j].sharedMaterials = srcMats;
                    }
                }

            }

            for (int j = 0; j < allParticleSystemRenderers.Length; j++)
            {
                Material[] srcMats = allParticleSystemRenderers[j].sharedMaterials;
                if (srcMats != null)
                {
                    bool needSaveMats = false;
                    for (int k = 0; k < srcMats.Length; k++)
                    {
                        type = MatType.Normal;
                        if (GetReplacedMatType(srcMats[k]) != MatType.Normal)
                        {
                            needSaveMats = true;
                            needSave = true;
                            srcMats[k] = typeAndMaterial[type];
                        }
                    }
                    if (needSaveMats)
                    {
                        allParticleSystemRenderers[j].sharedMaterials = srcMats;
                    }
                }

                Material trailMat = allParticleSystemRenderers[j].trailMaterial;
                type = MatType.Normal;
                if (GetReplacedMatType(trailMat) != MatType.Normal)
                {
                    needSave = true;
                    allParticleSystemRenderers[j].trailMaterial = typeAndMaterial[type];
                }
            }

            return needSave;
        }

        #region SceneObject
        //所有场景中的所有物体中的内置的几种材质shader替换掉
        static void ChangeSceneObjDefaultMat()
        {
            string headPath = Application.dataPath;
            //eg:D:/Project/Test/
            headPath = headPath.Substring(0, headPath.IndexOf("Assets"));

            List<string> optimizedOriginalScenePaths = new List<string>();
            TextureModifier.AddRootSourcePathToList("Assets/Snowstorm", headPath, "Scene", ref optimizedOriginalScenePaths); ///Env/Scenes

            for (int i = 0; i < optimizedOriginalScenePaths.Count; i++)
            {
                EditorUtility.DisplayProgressBar("ChangeSceneObjDefaultMat", "Scene -> " + optimizedOriginalScenePaths[i], i / optimizedOriginalScenePaths.Count);
                EditorSceneManager.OpenScene(optimizedOriginalScenePaths[i], OpenSceneMode.Single);
                GameObject[] gameObject = UnityEngine.Object.FindObjectsOfType<GameObject>();
                bool needSave = false;
                for (int k = 0; k < gameObject.Length; k++)
                {
                    needSave = CheckAndReplaceObjectMats(ref gameObject[k]);
                }

                if (needSave)
                {
                    EditorSceneManager.SaveScene(SceneManager.GetActiveScene());
                }
            }
            EditorUtility.ClearProgressBar();
        }
        #endregion

        #region prefabFix
        // 所有prefab检查修改
        [MenuItem("Assets/Shader/FixPrefabStandardShader")]
        static void FixPrefabStandardShader()
        {
            InitReplacedMats();
            Scene newScene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);
            Lightmapping.giWorkflowMode = Lightmapping.GIWorkflowMode.OnDemand;

            Dictionary<string, bool> wrongStandardPrefabList = new Dictionary<string, bool>();
            Dictionary<string, bool> wrongSpritePrefabList = new Dictionary<string, bool>();
            Dictionary<string, bool> wrongParticleSystemPrefabList = new Dictionary<string, bool>();

            Dictionary<MatType, Dictionary<string, bool>> wrongPrefabList = new Dictionary<MatType, Dictionary<string, bool>>();
            wrongPrefabList.Add(MatType.ParticleSystem, wrongParticleSystemPrefabList);
            wrongPrefabList.Add(MatType.Sprite, wrongSpritePrefabList);
            wrongPrefabList.Add(MatType.Standard, wrongStandardPrefabList);

            bool needSave = false;

            List<Material> ms = new List<Material>();
            GameObject prefabObj = null;

            string[] prefabGUIDArray = AssetDatabase.FindAssets("t:prefab", new string[1] { "Assets" });
            for (int i = 0; i < prefabGUIDArray.Length; i++)
            {
                string path = AssetDatabase.GUIDToAssetPath(prefabGUIDArray[i]);
                var asset = AssetDatabase.LoadAssetAtPath<GameObject>(path);
                if (asset == null)
                {
                    continue;
                }

                prefabObj = PrefabUtility.InstantiatePrefab(asset, SceneManager.GetActiveScene()) as GameObject;
                EditorUtility.DisplayProgressBar("FixPrefabStandardShader", "Prefab -> " + prefabObj.name, i / prefabGUIDArray.Length);

                needSave = CheckAndReplaceObjectMats(ref prefabObj);

                if (needSave)
                {
                    PrefabUtility.SaveAsPrefabAsset(prefabObj, path);
                }
            }
            EditorUtility.ClearProgressBar();
            Scene scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single);

        }
        #endregion

        //#region checkAgain
        //static void CheckAgain()
        //{
        //    var dict = new Dictionary<string, bool>();

        //    foreach (var assetBundleName in AssetDatabase.GetAllAssetBundleNames())
        //    {
        //        string[] assetPaths = AssetDatabase.GetAssetPathsFromAssetBundle(assetBundleName);
        //        foreach (var dependency in AssetDatabase.GetDependencies(assetPaths, true))
        //        {
        //            if (!dict.ContainsKey(dependency))
        //            {
        //                Debug.Log(dependency + "        111111111         " + assetPaths);
        //                dict.Add(dependency, true);
        //            }
        //        }
        //    }

        //    var di = new DirectoryInfo("Assets");
        //    foreach (var fi in di.GetFiles("*", SearchOption.AllDirectories))
        //    {
        //        if (fi.Extension == ".meta")
        //        {
        //            continue;
        //        }

        //        string assetPath = fi.FullName.Replace(Application.dataPath, "Assets");
        //        foreach (var dependency in AssetDatabase.GetDependencies(assetPath, true))
        //        {
        //            if (!dict.ContainsKey(dependency))
        //            {
        //                Debug.Log(dependency + "       2222222222         " + assetPath);
        //                dict.Add(dependency, true);
        //            }
        //        }
        //    }

        //    string[] scenes = (from scene in EditorBuildSettings.scenes
        //                       where scene.enabled
        //                       select scene.path).ToArray();
        //    foreach (var dependency in AssetDatabase.GetDependencies(scenes, true))
        //    {
        //        if (!dict.ContainsKey(dependency))
        //        {
        //            Debug.Log(dependency + "  33333333333         ");
        //            dict.Add(dependency, true);
        //        }
        //    }

        //    var materials = new List<Material>();
        //    var shaderDict = new Dictionary<Shader, List<Material>>();
        //    foreach (var assetPath in dict.Keys)
        //    {
        //        var material = AssetDatabase.LoadAssetAtPath<Material>(assetPath);
        //        if (material != null)
        //        {
        //            if (material.shader != null)
        //            {
        //                if (shadersInProject.Contains(material.shader))
        //                {
        //                    continue;
        //                }
        //                else
        //                {
        //                    if(!noEnvenSameNameMat.Contains(material))
        //                    {
        //                        noEnvenSameNameMat.Add(material);
        //                        NotFoundShaderList.Add(material.name);
        //                    }
        //                }
        //            }

        //        }
        //    }

        //    FileStream fs = new FileStream(Application.dataPath + "/NotFoundShader.txt", FileMode.Create);
        //    //存储时时二进制,所以这里需要把我们的字符串转成二进制


        //    byte[] bytesElement = new UTF8Encoding().GetBytes("没找到的shader: " + "\r\n");
        //    fs.Write(bytesElement, 0, bytesElement.Length);

        //    foreach (var item in NotFoundShaderList)
        //    {
        //        byte[] bytes = new UTF8Encoding().GetBytes(item + "\r\n");
        //        fs.Write(bytes, 0, bytes.Length);

        //    }

        //    bytesElement = new UTF8Encoding().GetBytes("没找到shader的材质: " + "\r\n");
        //    fs.Write(bytesElement, 0, bytesElement.Length);

        //    foreach (var item in noEnvenSameNameMat)
        //    {
        //        byte[] bytes = new UTF8Encoding().GetBytes(item + "\r\n");
        //        fs.Write(bytes, 0, bytes.Length);

        //    }

        //    byte[] bytesEnd = new UTF8Encoding().GetBytes("\r\n");
        //    fs.Write(bytesEnd, 0, bytesEnd.Length);
        //}
        //#endregion

        #region ExportAndSplit
        static void ExportShaderVariantAndSplit()
        {
            Debug.Log("ExportShaderVariantAndSplit +++                ------------");
            ShaderVariantCollectionExporter.Export();

            ShaderVariantCollection svc = AssetDatabase.LoadAllAssetsAtPath("Assets/Snowstorm/Shader/SVC_T.shadervariants")[0] as ShaderVariantCollection;

            if (Directory.Exists(Application.dataPath + "/Snowstorm/Shader/ShaderVariantBank"))
            {
                Directory.Delete(Application.dataPath + "/Snowstorm/Shader/ShaderVariantBank", true);
                Debug.Log("删除shaderVariantBank文件夹");
            }
            if (!Directory.Exists(Application.dataPath + "/Snowstorm/Shader/ShaderVariants"))
            {
                Directory.CreateDirectory(Application.dataPath + "/Snowstorm/Shader/ShaderVariants");
                Debug.Log("删除shaderVariants文件夹");
            }

            SplitShaderVariantsCollectionEditor.SplitShaderVariantCollection(svc);
            Debug.Log("All Succeed, please look at txt !!");
        }
        #endregion
    }
}

  

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM