-
Notifications
You must be signed in to change notification settings - Fork 0
/
MaterialTextureFixer.cs
148 lines (136 loc) · 6.85 KB
/
MaterialTextureFixer.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
using UnityEngine;
using UnityEditor;
using System.IO;
using System.Text;
using System.Linq;
using System.Collections.Generic;
using Unity.Plastic.Newtonsoft.Json;
namespace AhabTools
{
public class MaterialTextureFixer : EditorWindow
{
[MenuItem("Tools/Ahab Tools/Material Texture Fixer")]
public static void ShowWindow()
{
EditorWindow.GetWindow(typeof(MaterialTextureFixer), false, "Material Texture Fixer v1.0.0.");
}
void OnGUI()
{
#region Hyperlink
GUIStyle hyperlinkStyle = new GUIStyle();
hyperlinkStyle.normal.textColor = Color.gray;
hyperlinkStyle.fontStyle = FontStyle.Italic;
Rect linkRect = EditorGUILayout.GetControlRect();
if (GUI.Button(linkRect, "Click here to visit the GitHub repository of this tool to check the latest version.", hyperlinkStyle))
{
Application.OpenURL("https://github.com/ahabdeveloper/Unity-material-textures-tools");
}
#endregion
GUILayout.Space(5);
GUILayout.Label("Step 1. Save textures' paths.", EditorStyles.boldLabel);
EditorGUILayout.HelpBox("Registers and stores all the currently associated textures and their paths for any material selected in the Project tab. This information is stored in a JSON file created at the same location as the selected materials.", MessageType.Info);
if (GUILayout.Button("Store paths into JSON"))
{
SaveTexturesVariablesAndNamesToJson();
}
GUILayout.Label("Step 2. Refill textures.", EditorStyles.boldLabel);
EditorGUILayout.HelpBox("If one or more materials are selected in the Project Tab and there are JSON files as described above in the same path, the tool will read their content and reassign the texture files to the materials according to the annotations in the JSON files.", MessageType.Info);
if (GUILayout.Button("Refill Materials"))
{
RefillMaterialsFromJson();
}
}
#region Auxiliar methods
private static void SaveTexturesVariablesAndNamesToJson()
{
foreach (Object selectedObject in Selection.objects)
{
if (selectedObject is Material)
{
Material selectedMaterial = selectedObject as Material;
SaveMaterialTexturesToJson(selectedMaterial);
}
}
if (Selection.objects.Length == 0 || Selection.objects.All(obj => obj.GetType() != typeof(Material)))
{
Debug.Log("Please select one or more materials in the project tab.");
}
}
private static void SaveMaterialTexturesToJson(Material material)
{
string materialPath = AssetDatabase.GetAssetPath(material);
string directoryPath = Path.GetDirectoryName(materialPath);
Shader shader = material.shader;
StringBuilder jsonBuilder = new StringBuilder();
jsonBuilder.AppendLine("{");
jsonBuilder.AppendLine(" \"Textures\": [");
int propertyCount = ShaderUtil.GetPropertyCount(shader);
bool firstEntry = true;
for (int i = 0; i < propertyCount; i++)
{
if (ShaderUtil.GetPropertyType(shader, i) == ShaderUtil.ShaderPropertyType.TexEnv)
{
string propertyName = ShaderUtil.GetPropertyName(shader, i);
Texture texture = material.GetTexture(propertyName);
if (texture != null)
{
if (!firstEntry)
{
jsonBuilder.AppendLine(",");
}
jsonBuilder.AppendLine($" {{\"PropertyName\": \"{propertyName}\", \"TextureName\": \"{texture.name}\", \"FilePath\": \"{AssetDatabase.GetAssetPath(texture)}\"}}");
firstEntry = false;
}
}
}
jsonBuilder.AppendLine(" ]");
jsonBuilder.AppendLine("}");
string json = jsonBuilder.ToString();
string sanitizedMaterialName = material.name.Replace('/', '_').Replace('\\', '_').Replace(':', '_');
string fileName = $"{sanitizedMaterialName}_Textures.json";
string fullPath = Path.Combine(directoryPath, fileName);
File.WriteAllText(fullPath, json);
Debug.Log($"Texture variables and names saved to JSON file at {fullPath}");
}
private static void RefillMaterialsFromJson()
{
foreach (Object selectedObject in Selection.objects)
{
if (selectedObject is Material)
{
Material selectedMaterial = selectedObject as Material;
string materialPath = AssetDatabase.GetAssetPath(selectedMaterial);
string directoryPath = Path.GetDirectoryName(materialPath);
string sanitizedMaterialName = selectedMaterial.name.Replace('/', '_').Replace('\\', '_').Replace(':', '_');
string fileName = $"{sanitizedMaterialName}_Textures.json";
string fullPath = Path.Combine(directoryPath, fileName);
if (File.Exists(fullPath))
{
string json = File.ReadAllText(fullPath);
var textureInfoList = JsonConvert.DeserializeObject<Dictionary<string, List<Dictionary<string, string>>>>(json);
foreach (var item in textureInfoList["Textures"])
{
string propertyName = item["PropertyName"];
string filePath = item["FilePath"];
Texture texture = AssetDatabase.LoadAssetAtPath<Texture>(filePath);
if (texture != null)
{
selectedMaterial.SetTexture(propertyName, texture);
}
}
Debug.Log($"Textures refilled for material: {selectedMaterial.name}");
}
else
{
Debug.LogError($"JSON file not found for material: {selectedMaterial.name}");
}
}
}
if (Selection.objects.Length == 0 || Selection.objects.All(obj => obj.GetType() != typeof(Material)))
{
Debug.Log("Please select one or more materials in the project tab.");
}
}
#endregion
}
}