using System; using System.Collections.Generic; using System.IO; using System.Linq; using UnityEditor; using UnityEngine; /// /// 将未完全使用4张贴图的T4M材质裁剪到低消耗版本 /// public class T4MMaterialTrim { [MenuItem("ResourceTool/Fix T4M Material")] public static void TrimT4MMaterial() { var materialPath = (from assetPath in AssetDatabase.GetAllAssetPaths() let extension = Path.GetExtension(assetPath) where extension != null && extension.Equals(".mat", StringComparison.OrdinalIgnoreCase) select assetPath).ToArray(); var instance = new T4MMaterialTrim(materialPath); instance.Start(); } private readonly string[] _materialPaths; private Shader[] _t4MCommon; private Shader[] _t4MBump; private int _index; private T4MMaterialTrim(string[] materialPaths) { _materialPaths = materialPaths; } private void Start() { var error = false; _index = 0; _t4MCommon = new Shader[3]; if (!AddShader(_t4MCommon, 0, "Zhanyou/Scene/T2M 2 Textures")) error = true; if (!AddShader(_t4MCommon, 1, "Zhanyou/Scene/T3M 3 Textures")) error = true; if (!AddShader(_t4MCommon, 2, "Zhanyou/Scene/T4M 4 Textures")) error = true; _t4MBump = new Shader[3]; if (!AddShader(_t4MBump, 0, "Zhanyou/Scene/T2M 2 Textures Bump")) error = true; if (!AddShader(_t4MBump, 1, "Zhanyou/Scene/T3M 3 Textures Bump")) error = true; if (!AddShader(_t4MBump, 2, "Zhanyou/Scene/T4M 4 Textures Bump")) error = true; if (!error) EditorApplication.update = OnEditorUpdate; } private bool AddShader(IList array, int i, string shaderName) { var shader = Shader.Find(shaderName); if (shader == null) Debug.LogError("无法获得对应Shader " + shaderName); else array[i] = shader; return array[i] != null; } private void OnEditorUpdate() { try { if (_index < _materialPaths.Length) { var path = _materialPaths[_index]; var material = AssetDatabase.LoadAssetAtPath(path); if (material != null && material.shader != null) { if (_t4MCommon.Contain(material.shader)) { var level = GetShaderLevel(material, _t4MCommon); var newLevel = GetFixedShaderLevel(material, level); if (newLevel >= 0 && newLevel < level) { material.shader = _t4MCommon[newLevel]; EditorUtility.SetDirty(material); Debug.LogWarning(string.Format("T4M材质 {0}由{1}降低至{2}!", path, level + 2, newLevel + 2)); } } else if (_t4MBump.Contain(material.shader)) { var level = GetShaderLevel(material, _t4MBump); var newLevel = GetFixedShaderLevel(material, level); if (newLevel >= 0 && newLevel < level) { for(var i = newLevel; i < level; i++) { var bumpName = "_BumpSplat" + (i + 2); material.SetTexture(bumpName, null); } material.shader = _t4MBump[newLevel]; EditorUtility.SetDirty(material); Debug.LogWarning(string.Format("T4M法线材质 {0}由{1}降低至{2}!", path, level + 2, newLevel + 2)); } } } _index++; Debug.Log(string.Format("完成检查{0} / {1}", _index, _materialPaths.Length)); } else { EditorApplication.update = null; AssetDatabase.SaveAssets(); AssetDatabase.Refresh(); } } catch (Exception e) { EditorApplication.update = null; Debug.LogError(e.ToString()); } } private int GetShaderLevel(Material material, IList array) { return array.IndexOf(material.shader); } private int GetFixedShaderLevel(Material material, int level) { var error = false; var lastNull = true; var textureCount = 0; for (var i = level + 1; i >= 0; i--) { var colorName = "_Splat" + i; var texture = material.GetTexture(colorName); if (texture != null) textureCount++; else if (!lastNull) { error = true; break; } lastNull = texture == null; } if (error) { Debug.LogError(string.Format("材质{0}中间有贴图缺失!", AssetDatabase.GetAssetPath(material))); textureCount = 0; } else if (textureCount < 2) Debug.LogError(string.Format("材质{0}的有效贴图数目只有{1}", AssetDatabase.GetAssetPath(material), textureCount)); return textureCount - 2; } }