Skip to content

Instantly share code, notes, and snippets.

@mousedoc
Last active December 2, 2024 09:28
Show Gist options
  • Save mousedoc/2122ad8b654e5a3a838127d38fc28bd3 to your computer and use it in GitHub Desktop.
Save mousedoc/2122ad8b654e5a3a838127d38fc28bd3 to your computer and use it in GitHub Desktop.

Revisions

  1. mousedoc revised this gist Feb 26, 2020. 1 changed file with 47 additions and 18 deletions.
    65 changes: 47 additions & 18 deletions MaterialRefCleaner.cs
    Original file line number Diff line number Diff line change
    @@ -7,10 +7,39 @@ public class MaterialRefCleaner : EditorWindow
    private SerializedObject serializedObject;
    private Material selectedMaterial;

    [MenuItem("Tools/Optimization/MaterialRefCleaner", priority = 51)]
    private static void Init()
    [MenuItem("Tools/Optimization/Material/Open Material Reference Cleaner", priority = 51)]
    private static void ShowWindow()
    {
    GetWindow<MaterialRefCleaner>("Ref. Cleaner");
    var window = GetWindow<MaterialRefCleaner>("MatRef. Cleaner");
    window.Show();
    }

    [MenuItem("Tools/Optimization/Material/Clean All Material`s Reference", priority = 52)]
    private static void CleanAll()
    {
    foreach (var guid in AssetDatabase.FindAssets("t:Material"))
    {
    var path = AssetDatabase.GUIDToAssetPath(guid);
    var material = AssetDatabase.LoadAssetAtPath<Material>(path);
    var serializedObj = new SerializedObject(material);

    var properties = new List<SerializedProperty>()
    {
    GetSerializedProperty(serializedObj, "m_SavedProperties.m_TexEnvs"),
    GetSerializedProperty(serializedObj, "m_SavedProperties.m_Floats"),
    GetSerializedProperty(serializedObj, "m_SavedProperties.m_Colors"),
    };

    foreach (var property in properties)
    {
    RemoveAllOldReference(material, serializedObj, property);
    }
    }

    AssetDatabase.SaveAssets();
    AssetDatabase.Refresh();

    Debug.Log("<color=#83C8FF>[MaterialRefCleaner] Done - CleanAll()</color>");
    }

    protected virtual void OnEnable()
    @@ -41,9 +70,9 @@ protected virtual void OnGUI()
    {
    var propertyMap = new Dictionary<string, SerializedProperty>()
    {
    { "Textures", GetSerializedProperty("m_SavedProperties.m_TexEnvs") },
    { "Floats", GetSerializedProperty("m_SavedProperties.m_Floats") },
    { "Colors", GetSerializedProperty("m_SavedProperties.m_Colors") },
    { "Textures", GetSerializedProperty(serializedObject, "m_SavedProperties.m_TexEnvs") },
    { "Floats", GetSerializedProperty(serializedObject, "m_SavedProperties.m_Floats") },
    { "Colors", GetSerializedProperty(serializedObject, "m_SavedProperties.m_Colors") },
    };

    EditorGUILayout.Space();
    @@ -58,9 +87,9 @@ protected virtual void OnGUI()
    GUI.backgroundColor = Color.red;
    if (GUILayout.Button("Remove all"))
    {
    RemoveAllOldReference(propertyMap["Textures"]);
    RemoveAllOldReference(propertyMap["Floats"]);
    RemoveAllOldReference(propertyMap["Colors"]);
    RemoveAllOldReference(selectedMaterial, serializedObject, propertyMap["Textures"]);
    RemoveAllOldReference(selectedMaterial, serializedObject, propertyMap["Floats"]);
    RemoveAllOldReference(selectedMaterial, serializedObject, propertyMap["Colors"]);
    }

    GUI.backgroundColor = Color.cyan;
    @@ -100,9 +129,9 @@ protected virtual void OnGUI()
    EditorGUIUtility.labelWidth = 0;
    }

    private SerializedProperty GetSerializedProperty(string path)
    private static SerializedProperty GetSerializedProperty(SerializedObject serializedObj, string path)
    {
    return serializedObject.FindProperty(path);
    return serializedObj.FindProperty(path);
    }

    private void ProcessProperties(SerializedProperty properties)
    @@ -135,19 +164,19 @@ private void ProcessProperties(SerializedProperty properties)
    }
    }

    private void RemoveAllOldReference(SerializedProperty properties)
    private static void RemoveAllOldReference(Material material ,SerializedObject serializedObj, SerializedProperty property)
    {
    if (properties != null && properties.isArray)
    if (property != null && property.isArray)
    {
    for (int i = 0; i < properties.arraySize; i++)
    for (int i = 0; i < property.arraySize; i++)
    {
    string name = properties.GetArrayElementAtIndex(i).displayName;
    bool exist = selectedMaterial.HasProperty(name);
    string name = property.GetArrayElementAtIndex(i).displayName;
    bool exist = material.HasProperty(name);

    if (exist == false)
    {
    properties.DeleteArrayElementAtIndex(i);
    serializedObject.ApplyModifiedProperties();
    property.DeleteArrayElementAtIndex(i);
    serializedObj.ApplyModifiedProperties();
    i--;
    }
    }
  2. mousedoc revised this gist Feb 24, 2020. No changes.
  3. mousedoc revised this gist Feb 24, 2020. No changes.
  4. mousedoc created this gist Feb 24, 2020.
    167 changes: 167 additions & 0 deletions MaterialRefCleaner.cs
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,167 @@
    using System.Collections.Generic;
    using UnityEditor;
    using UnityEngine;

    public class MaterialRefCleaner : EditorWindow
    {
    private SerializedObject serializedObject;
    private Material selectedMaterial;

    [MenuItem("Tools/Optimization/MaterialRefCleaner", priority = 51)]
    private static void Init()
    {
    GetWindow<MaterialRefCleaner>("Ref. Cleaner");
    }

    protected virtual void OnEnable()
    {
    UpdateSelectedMaterial();
    }

    protected virtual void OnSelectionChange()
    {
    UpdateSelectedMaterial();
    }

    protected virtual void OnProjectChange()
    {
    UpdateSelectedMaterial();
    }

    private Vector2 scrollPos = Vector2.zero;
    protected virtual void OnGUI()
    {
    EditorGUIUtility.labelWidth = 200f;

    if (selectedMaterial == null)
    {
    EditorGUILayout.LabelField("No material selected");
    }
    else
    {
    var propertyMap = new Dictionary<string, SerializedProperty>()
    {
    { "Textures", GetSerializedProperty("m_SavedProperties.m_TexEnvs") },
    { "Floats", GetSerializedProperty("m_SavedProperties.m_Floats") },
    { "Colors", GetSerializedProperty("m_SavedProperties.m_Colors") },
    };

    EditorGUILayout.Space();
    EditorGUILayout.LabelField("Selected material:", selectedMaterial.name);
    EditorGUILayout.LabelField("Shader:", selectedMaterial.shader.name);

    #region Quick behaviour

    EditorGUILayout.BeginHorizontal();

    Color originColor = GUI.backgroundColor;
    GUI.backgroundColor = Color.red;
    if (GUILayout.Button("Remove all"))
    {
    RemoveAllOldReference(propertyMap["Textures"]);
    RemoveAllOldReference(propertyMap["Floats"]);
    RemoveAllOldReference(propertyMap["Colors"]);
    }

    GUI.backgroundColor = Color.cyan;
    if (GUILayout.Button("Save"))
    {
    AssetDatabase.SaveAssets();
    AssetDatabase.Refresh();
    }

    GUI.backgroundColor = originColor;
    EditorGUILayout.EndHorizontal();

    #endregion

    EditorGUILayout.LabelField("", GUI.skin.horizontalSlider);

    scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
    EditorGUILayout.LabelField("Properties");

    serializedObject.Update();

    EditorGUI.indentLevel++;

    foreach (var pair in propertyMap)
    {
    EditorGUILayout.LabelField(pair.Key);
    EditorGUI.indentLevel++;
    ProcessProperties(pair.Value);
    EditorGUI.indentLevel--;
    }

    EditorGUI.indentLevel--;
    EditorGUILayout.EndScrollView();
    EditorGUILayout.Space();
    }

    EditorGUIUtility.labelWidth = 0;
    }

    private SerializedProperty GetSerializedProperty(string path)
    {
    return serializedObject.FindProperty(path);
    }

    private void ProcessProperties(SerializedProperty properties)
    {
    if (properties != null && properties.isArray)
    {
    for (int i = 0; i < properties.arraySize; i++)
    {
    string name = properties.GetArrayElementAtIndex(i).displayName;
    bool exist = selectedMaterial.HasProperty(name);

    if (exist)
    {
    EditorGUILayout.LabelField(name, "Exist");
    }
    else
    {
    using (new EditorGUILayout.HorizontalScope())
    {
    EditorGUILayout.LabelField(name, "Old reference", "CN StatusWarn");
    if (GUILayout.Button("Remove", GUILayout.Width(80f)))
    {
    properties.DeleteArrayElementAtIndex(i);
    serializedObject.ApplyModifiedProperties();
    GUIUtility.ExitGUI();
    }
    }
    }
    }
    }
    }

    private void RemoveAllOldReference(SerializedProperty properties)
    {
    if (properties != null && properties.isArray)
    {
    for (int i = 0; i < properties.arraySize; i++)
    {
    string name = properties.GetArrayElementAtIndex(i).displayName;
    bool exist = selectedMaterial.HasProperty(name);

    if (exist == false)
    {
    properties.DeleteArrayElementAtIndex(i);
    serializedObject.ApplyModifiedProperties();
    i--;
    }
    }
    }
    }

    private void UpdateSelectedMaterial()
    {
    selectedMaterial = Selection.activeObject as Material;
    if (selectedMaterial != null)
    {
    serializedObject = new SerializedObject(selectedMaterial);
    }

    Repaint();
    }
    }