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();
}
}
}