欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Unity处理材质球过期属性工具

程序员文章站 2022-06-11 07:53:52
...

 Unity中的材质属性被序列化以后,就会一直存储在资源中,即使该属性删除后,它的序列化值以及引用关系也不会被丢掉,所以我们经常会发现,当我们使用一个和之前命名相同的属性时,原来的属性值或资源就会被自动赋值,这是因为材质中一直保持这种关系;但是,有些时候我们为了优化或者其它需求,想要去清理掉这些引用关系,如下,给出了清理某个文件夹下所有材质过期属性的一个工具;

参考:游戏资源工具(一):Unity中处理材质球过期属性工具

using UnityEngine;
using UnityEditor;

public class MatObseletePropertyWindow : EditorWindow
{
    public static string assetFolderPath = "Assets/Scenes";
    [MenuItem ("Tools/移除材质中的废弃属性")]
    public static void ShowWindow () {
        EditorWindow thisWindow = EditorWindow.GetWindow(typeof(MatObseletePropertyWindow));
        thisWindow.titleContent = new GUIContent("统计并移除材质中的无用属性");
        thisWindow.position = new Rect(Screen.width/2, Screen.height/2, 600, 1000);
    }

    public static void ClearMatObseleteProperty()
    {
        Debug.Log(Application.dataPath);
        string projectPath = Application.dataPath.Replace("Assets", "");
        assetFolderPath = assetFolderPath.Replace(projectPath, "");
        var matList = AssetDatabase.FindAssets("t:Material", new[] {assetFolderPath});
 
        foreach(var i in matList)
        {
            // EditorUtility.DisplayProgressBar("材质属性移除统计文件", "正在写入统计文件中...", ix/shaderList.Length);
            var path = AssetDatabase.GUIDToAssetPath(i);
            Material mat = AssetDatabase.LoadAssetAtPath(path, typeof(Material)) as Material;
            Debug.Log(mat.name);
            SerializedObject so = new SerializedObject(mat);
            SerializedProperty m_SavedProperties = so.FindProperty("m_SavedProperties");
            RemoveElement(mat, "m_TexEnvs", m_SavedProperties);
            RemoveElement(mat, "m_Floats", m_SavedProperties);
            RemoveElement(mat, "m_Colors", m_SavedProperties);
            so.ApplyModifiedProperties();
        }
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
    private static void RemoveElement(Material mat, string spName, SerializedProperty saveProperty){
        SerializedProperty property = saveProperty.FindPropertyRelative(spName);
            for(int i = property.arraySize - 1; i >= 0; i--){
                var prop = property.GetArrayElementAtIndex(i);
                string propertyName = prop.displayName;
                if (!mat.HasProperty(propertyName))
                {
                    property.DeleteArrayElementAtIndex(i);
                    Debug.Log("移除属性名称" + propertyName);
                }
            }
    }
    void OnGUI()
    {
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.LabelField("选择文件夹");
        EditorGUILayout.TextField(assetFolderPath);
        if (GUILayout.Button("选择"))
        {
            assetFolderPath = EditorUtility.OpenFolderPanel("选择文件夹", assetFolderPath, "");
        }
        EditorGUILayout.EndHorizontal();
 
        if (GUILayout.Button("确定") && assetFolderPath != null)
        {
            ClearMatObseleteProperty();
        }
    }
}

 

相关标签: Unity Editor