AxibugEmuOnline/AxibugEmuOnline.Client/Assets/Plugins/Coffee/UIExtensions/UIEffect/Scripts/Common/MaterialResolver.cs

127 lines
4.2 KiB
C#
Raw Normal View History

2024-08-16 14:45:44 +08:00
#if UNITY_EDITOR
using System.Collections.Generic;
2024-12-04 23:15:05 +08:00
using System.IO;
2024-08-16 14:45:44 +08:00
using System.Linq;
using System.Text;
using UnityEditor;
using UnityEngine;
namespace Coffee.UIExtensions
{
2024-12-04 23:15:05 +08:00
public class MaterialResolver
{
static readonly StringBuilder s_StringBuilder = new StringBuilder();
2024-08-16 14:45:44 +08:00
2024-12-04 23:15:05 +08:00
static readonly Dictionary<string, Material> s_MaterialMap = new Dictionary<string, Material>();
2024-08-16 14:45:44 +08:00
2024-12-04 23:15:05 +08:00
public static Material GetOrGenerateMaterialVariant(Shader shader, params object[] append)
{
if (!shader)
{
return null;
}
2024-08-16 14:45:44 +08:00
2024-12-04 23:15:05 +08:00
Material mat = null;
string variantName = GetVariantName(shader, append);
if (s_MaterialMap.TryGetValue(variantName, out mat) && mat)
{
return mat;
}
2024-08-16 14:45:44 +08:00
2024-12-04 23:15:05 +08:00
string[] keywords = append.Where(x => 0 < (int)x)
.Select(x => x.ToString().ToUpper())
.ToArray();
mat = GetMaterial(shader, append);
if (mat)
{
if (!mat.shaderKeywords.OrderBy(x => x).SequenceEqual(keywords.OrderBy(x => x)))
{
mat.shaderKeywords = keywords;
EditorUtility.SetDirty(mat);
if (!Application.isPlaying)
{
EditorApplication.delayCall += AssetDatabase.SaveAssets;
}
}
return mat;
}
2024-08-16 14:45:44 +08:00
2024-12-04 23:15:05 +08:00
if (s_MaterialMap.TryGetValue(variantName, out mat) && mat)
{
return mat;
}
2024-08-16 14:45:44 +08:00
2024-12-04 23:15:05 +08:00
Debug.Log("Generate material : " + variantName);
mat = new Material(shader);
mat.shaderKeywords = keywords;
2024-08-16 14:45:44 +08:00
2024-12-04 23:15:05 +08:00
mat.name = variantName;
mat.hideFlags |= HideFlags.NotEditable;
s_MaterialMap[variantName] = mat;
2024-08-16 14:45:44 +08:00
2024-12-04 23:15:05 +08:00
bool isMainAsset = append.Cast<int>().All(x => x == 0);
EditorApplication.delayCall += () => SaveMaterial(mat, shader, isMainAsset);
return mat;
}
2024-08-16 14:45:44 +08:00
2024-12-04 23:15:05 +08:00
static void SaveMaterial(Material mat, Shader shader, bool isMainAsset)
{
string materialPath = GetDefaultMaterialPath(shader);
2024-08-16 14:45:44 +08:00
#if UIEFFECT_SEPARATE
string dir = Path.GetDirectoryName(materialPath);
materialPath = Path.Combine(Path.Combine(dir, "Separated"), mat.name + ".mat");
isMainAsset = true;
#endif
2024-12-04 23:15:05 +08:00
if (isMainAsset)
{
Directory.CreateDirectory(Path.GetDirectoryName(materialPath));
AssetDatabase.CreateAsset(mat, materialPath);
}
else
{
GetOrGenerateMaterialVariant(shader);
mat.hideFlags |= HideFlags.HideInHierarchy;
AssetDatabase.AddObjectToAsset(mat, materialPath);
}
AssetDatabase.SaveAssets();
}
2024-08-16 14:45:44 +08:00
2024-12-04 23:15:05 +08:00
public static Material GetMaterial(Shader shader, params object[] append)
{
string variantName = GetVariantName(shader, append);
return AssetDatabase.FindAssets("t:Material " + Path.GetFileName(shader.name))
.Select(x => AssetDatabase.GUIDToAssetPath(x))
.SelectMany(x => AssetDatabase.LoadAllAssetsAtPath(x))
.OfType<Material>()
.FirstOrDefault(x => x.name == variantName);
}
2024-08-16 14:45:44 +08:00
2024-12-04 23:15:05 +08:00
public static string GetDefaultMaterialPath(Shader shader)
{
var name = Path.GetFileName(shader.name);
return AssetDatabase.FindAssets("t:Material " + name)
.Select(x => AssetDatabase.GUIDToAssetPath(x))
.FirstOrDefault(x => Path.GetFileNameWithoutExtension(x) == name)
?? ("Assets/" + name + ".mat");
}
2024-08-16 14:45:44 +08:00
2024-12-04 23:15:05 +08:00
public static string GetVariantName(Shader shader, params object[] append)
{
s_StringBuilder.Length = 0;
2024-08-16 14:45:44 +08:00
#if UIEFFECT_SEPARATE
s_StringBuilder.Append("[Separated] ");
#endif
2024-12-04 23:15:05 +08:00
s_StringBuilder.Append(Path.GetFileName(shader.name));
foreach (object mode in append.Where(x => 0 < (int)x))
{
s_StringBuilder.Append("-");
s_StringBuilder.Append(mode.ToString());
}
return s_StringBuilder.ToString();
}
}
2024-08-16 14:45:44 +08:00
}
#endif