删除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 } }