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