155 lines
5.4 KiB
C#
155 lines
5.4 KiB
C#
|
using System;
|
|||
|
using System.Collections.Generic;
|
|||
|
using System.IO;
|
|||
|
using System.Linq;
|
|||
|
using UnityEditor;
|
|||
|
using UnityEngine;
|
|||
|
/// <summary>
|
|||
|
/// 将未完全使用4张贴图的T4M材质裁剪到低消耗版本
|
|||
|
/// </summary>
|
|||
|
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<Shader> 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<Material>(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<Shader> 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;
|
|||
|
}
|
|||
|
}
|