using UnityEngine; using UnityEditor; using System.Collections.Generic; public class MaterialCleaner : EditorWindow { [MenuItem("Tools/清理材质无效属性/关键词")] static void CleanMaterials() { var materials = Selection.GetFiltered(SelectionMode.DeepAssets); if (materials.Length == 0) { Debug.LogWarning("请先选中要清理的材质!"); return; } foreach (var mat in materials) { if (mat.shader == null) continue; Debug.Log($"🧹 清理材质: {mat.name}"); // 获取当前 Shader 的所有属性名(合法字段) var validProps = new HashSet(); int count = ShaderUtil.GetPropertyCount(mat.shader); for (int i = 0; i < count; i++) { validProps.Add(ShaderUtil.GetPropertyName(mat.shader, i)); } // 清理无效贴图 var so = new SerializedObject(mat); var texEnvs = so.FindProperty("m_SavedProperties.m_TexEnvs"); for (int i = texEnvs.arraySize - 1; i >= 0; i--) { var prop = texEnvs.GetArrayElementAtIndex(i); var name = prop.FindPropertyRelative("first").stringValue; if (!validProps.Contains(name)) { Debug.Log($" ⛔ 移除无效贴图属性: {name}"); texEnvs.DeleteArrayElementAtIndex(i); } } // 清理无效 Float/Range var floats = so.FindProperty("m_SavedProperties.m_Floats"); for (int i = floats.arraySize - 1; i >= 0; i--) { var prop = floats.GetArrayElementAtIndex(i); var name = prop.FindPropertyRelative("first").stringValue; if (!validProps.Contains(name)) { Debug.Log($" ⛔ 移除无效数值属性: {name}"); floats.DeleteArrayElementAtIndex(i); } } // 清理无效 Colors var colors = so.FindProperty("m_SavedProperties.m_Colors"); for (int i = colors.arraySize - 1; i >= 0; i--) { var prop = colors.GetArrayElementAtIndex(i); var name = prop.FindPropertyRelative("first").stringValue; if (!validProps.Contains(name)) { Debug.Log($" ⛔ 移除无效颜色属性: {name}"); colors.DeleteArrayElementAtIndex(i); } } // 清理无效 keyword string[] allKeywords = mat.shaderKeywords; List newKeywords = new List(); foreach (var keyword in allKeywords) { if (Shader.IsKeywordEnabled(keyword)) // optional check, based on usage { newKeywords.Add(keyword); // optional: keep all or filter known list } } mat.shaderKeywords = newKeywords.ToArray(); so.ApplyModifiedProperties(); EditorUtility.SetDirty(mat); } AssetDatabase.SaveAssets(); Debug.Log("✅ 材质清理完成!"); } }