758 lines
29 KiB
C#
758 lines
29 KiB
C#
using System.Collections.Generic;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
using System.IO;
|
||
using TMPro;
|
||
using System;
|
||
using UnityEngine.TextCore.LowLevel;
|
||
using TMPro.EditorUtilities;
|
||
using Object = UnityEngine.Object;
|
||
using System.Reflection;
|
||
|
||
namespace BFEditor.Resource
|
||
{
|
||
public class TMPTools
|
||
{
|
||
#region GenTMPFontAsset - version 1.4.1
|
||
private const int FontSize = 32;
|
||
private const int Padding = 4;
|
||
|
||
private const GlyphRenderMode GRenderMode = GlyphRenderMode.SDFAA;
|
||
|
||
private const string tmpFontsPath = "Assets/arts/fonts/tmpfonts/";
|
||
|
||
private const string subFontPath = "/tmpfont";
|
||
|
||
private const string subTTFPath = "/tmpfont";
|
||
private const string AssetCNName = "font_cn_sdf.asset";
|
||
private const string AssetDefaultName = "font_sdf.asset";
|
||
private const string AssetNumberName = "font_number_sdf.asset";
|
||
private const string AssetBattleName = "font_battle_sdf.asset";
|
||
private const string AssetThaiName = "font_thai_sdf.asset";
|
||
private const string AssetJaName = "font_ja_sdf.asset";
|
||
|
||
private const string DevStrPath = "Assets/Editor/BFResourceTools/FontTools/cn_3900.txt";
|
||
private const string CommonCNWordsPath = "Assets/Editor/BFResourceTools/FontTools/cn_1200.txt";
|
||
private const string CommonZHWordsPath = "Assets/Editor/BFResourceTools/FontTools/zh_1200.txt";
|
||
|
||
private const string commonStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789¥…()—:”“‘《》?、·!【】;’,。+-*/`-=!@#$%^&*()_+[];',.\\~{}|:<>?\" ";
|
||
|
||
private const string defaultFontPath = "Assets/arts/fonts/tmpfonts/default/tmpfont/font_sdf.asset";
|
||
|
||
private class TTFInfo
|
||
{
|
||
public string language;
|
||
public string fontFolder;
|
||
public string ttfPath;
|
||
public int atlasSize;
|
||
public List<string> wordsPath;
|
||
|
||
public TTFInfo(string language, int atlasSize, List<string> words)
|
||
{
|
||
this.language = language;
|
||
fontFolder = tmpFontsPath + language + subFontPath;
|
||
ttfPath = tmpFontsPath + language + subTTFPath;
|
||
this.atlasSize = atlasSize;
|
||
wordsPath = new List<string>();
|
||
|
||
if (words != null)
|
||
{
|
||
foreach (var word in words)
|
||
{
|
||
var tmp = Application.dataPath + "/Developer/lua/app/config/strings/" + word;
|
||
wordsPath.Add(tmp);
|
||
}
|
||
}
|
||
}
|
||
|
||
public TTFInfo(string language, string fontFolder, string ttfPath, int atlasSize, List<string> wordsPath)
|
||
{
|
||
this.language = language;
|
||
this.fontFolder = fontFolder;
|
||
this.ttfPath = ttfPath;
|
||
this.atlasSize = atlasSize;
|
||
this.wordsPath = wordsPath;
|
||
}
|
||
}
|
||
|
||
private static List<TTFInfo> ttfInfos = new List<TTFInfo>()
|
||
{
|
||
new TTFInfo("en", 512, new List<string>(){"en"}),
|
||
new TTFInfo("cn", 2048, new List<string>(){"cn"}),
|
||
// new TTFInfo("fr", 512, new List<string>(){"fr"}),
|
||
// new TTFInfo("de", 512, new List<string>(){"de"}),
|
||
// new TTFInfo("it", 512, new List<string>(){"it"}),
|
||
// new TTFInfo("ms", 512, new List<string>(){"ms"}),
|
||
// new TTFInfo("pt", 512, new List<string>(){"pt"}),
|
||
// new TTFInfo("es", 512, new List<string>(){"es"}),
|
||
// new TTFInfo("tr", 512, new List<string>(){"tr"}),
|
||
new TTFInfo("id", 512, new List<string>(){"id"}),
|
||
new TTFInfo("ru", 512, new List<string>(){"ru"}),
|
||
// new TTFInfo("kr", 512, new List<string>(){"kr"}),
|
||
new TTFInfo("zh", 2048, new List<string>(){"zh"}),
|
||
new TTFInfo("th", 512, new List<string>(){"th"}),
|
||
// new TTFInfo("ja", 512, new List<string>(){"ja"}),
|
||
new TTFInfo("vi", 512, new List<string>(){"vi"}),
|
||
};
|
||
|
||
|
||
#if UNITY_EDITOR_OSX
|
||
private static bool ProgramerOrDesigner = true;
|
||
#else
|
||
private static bool ProgramerOrDesigner = false;
|
||
#endif
|
||
|
||
static public void GenFormalFontAsset(bool isdevelop)
|
||
{
|
||
Debug.Log("[bfinfo]生成TMP字体...");
|
||
|
||
GenAllTMPFontAsset(isdevelop);
|
||
}
|
||
|
||
static private void GenAllTMPFontAsset(bool isdevelop)
|
||
{
|
||
// foreach (var ttfInfo in ttfInfos)
|
||
// {
|
||
// var dir = new DirectoryInfo(ttfInfo.ttfPath);
|
||
// var allFiles = dir.GetFiles("*", SearchOption.AllDirectories);
|
||
// if (null != allFiles)
|
||
// {
|
||
// foreach (var ttfPath in allFiles)
|
||
// {
|
||
// var fullName = ttfPath.FullName;
|
||
// if (fullName.ToLower().EndsWith(".ttf") || fullName.ToLower().EndsWith(".otf"))
|
||
// {
|
||
// var path = BF.Utils.GetAssetPathByFullPath(fullName);
|
||
// var font = AssetDatabase.LoadAssetAtPath<Font>(path);
|
||
// if (!font)
|
||
// {
|
||
// Debug.LogError("Can't find font sourcefile !");
|
||
// continue;
|
||
// }
|
||
// if(fullName.IndexOf("title") != -1)
|
||
// {
|
||
// GenTMPFontAsset(font, ttfInfo, AssetNumberName, false, false);
|
||
// }
|
||
// else
|
||
// {
|
||
// GenTMPFontAsset(font, ttfInfo, AssetDefaultName, false, false);
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
// }
|
||
|
||
// var atlasSize = isdevelop ? 4096 : 256;
|
||
|
||
// 常用中文
|
||
// var defaultCNFont = AssetDatabase.LoadAssetAtPath<Font>("Assets/arts/fonts/tmpfonts/default/tmpfont/font_cn.TTF");
|
||
// GenTMPFontAsset(defaultCNFont, new TTFInfo("cn", "Assets/arts/fonts/tmpfonts/default/tmpfont", "Assets/arts/fonts/tmpfonts/default/tmpfont", 256, new List<string>()), AssetCNName, isdevelop);
|
||
|
||
// 常用
|
||
var defaultFont = AssetDatabase.LoadAssetAtPath<Font>("Assets/arts/fonts/tmpfonts/default/tmpfont/font_default.TTF");
|
||
GenTMPFontAsset(defaultFont, new TTFInfo("cn", "Assets/arts/fonts/tmpfonts/default/tmpfont", "Assets/arts/fonts/tmpfonts/default/tmpfont", 2048, new List<string>()), AssetDefaultName, isdevelop);
|
||
|
||
// 数字用
|
||
var defaultNumberFont = AssetDatabase.LoadAssetAtPath<Font>("Assets/arts/fonts/tmpfonts/default/tmpfont/font_number.TTF");
|
||
GenTMPFontAsset(defaultNumberFont, new TTFInfo("cn", "Assets/arts/fonts/tmpfonts/default/tmpfont", "Assets/arts/fonts/tmpfonts/default/tmpfont", 256, new List<string>()), AssetNumberName, isdevelop);
|
||
|
||
// 泰语
|
||
var thaiFont = AssetDatabase.LoadAssetAtPath<Font>("Assets/arts/fonts/tmpfonts/default/tmpfont/font_thai.ttf");
|
||
GenTMPFontAsset(thaiFont, new TTFInfo("cn", "Assets/arts/fonts/tmpfonts/default/tmpfont", "Assets/arts/fonts/tmpfonts/default/tmpfont", 512, new List<string>()), AssetThaiName, isdevelop);
|
||
|
||
// 日语
|
||
var jaFont = AssetDatabase.LoadAssetAtPath<Font>("Assets/arts/fonts/tmpfonts/default/tmpfont/font_ja.ttf");
|
||
GenTMPFontAsset(jaFont, new TTFInfo("cn", "Assets/arts/fonts/tmpfonts/default/tmpfont", "Assets/arts/fonts/tmpfonts/default/tmpfont", 512, new List<string>()), AssetJaName, isdevelop);
|
||
|
||
// 战斗用
|
||
// var battleFont = AssetDatabase.LoadAssetAtPath<Font>("Assets/arts/fonts/tmpfonts/battle/font_battle.ttf");
|
||
// GenTMPFontAsset(battleFont, new TTFInfo("cn", "Assets/arts/fonts/tmpfonts/battle", "Assets/arts/fonts/tmpfonts/battle", 1024, new List<string>()), AssetBattleName, isdevelop);
|
||
|
||
AssetDatabase.SaveAssets();
|
||
AssetDatabase.Refresh();
|
||
}
|
||
|
||
static private void GetWords(bool isDevelop, bool isDefaultFont, List<string> luaFolderPaths, string language, out string words)
|
||
{
|
||
words = string.Empty;
|
||
|
||
//是否开发模式
|
||
if (!isDevelop)
|
||
{
|
||
var text = LocalizationMenuTools.CatWordsFromLuaConfig(luaFolderPaths);
|
||
foreach (var w in text)
|
||
{
|
||
if (!words.Contains(w.ToString()))
|
||
words += w;
|
||
}
|
||
|
||
if(language.CompareTo("cn") != -1)
|
||
{
|
||
// 简体常用字
|
||
var textAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(CommonCNWordsPath);
|
||
foreach (var w in textAsset.text)
|
||
{
|
||
if (!words.Contains(w.ToString()))
|
||
words += w;
|
||
}
|
||
}
|
||
else if(language.CompareTo("zh") != -1)
|
||
{
|
||
// 繁体常用字
|
||
var textAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(CommonZHWordsPath);
|
||
foreach (var w in textAsset.text)
|
||
{
|
||
if (!words.Contains(w.ToString()))
|
||
words += w;
|
||
}
|
||
}
|
||
}
|
||
else
|
||
{
|
||
// 常用字母和数字还有符号
|
||
foreach (var w in commonStr)
|
||
{
|
||
if (!words.Contains(w.ToString()))
|
||
words += w;
|
||
}
|
||
|
||
var luaConfigText = LocalizationMenuTools.CatWordsFromLuaConfig(luaFolderPaths);
|
||
foreach (var w in luaConfigText)
|
||
{
|
||
if (!words.Contains(w.ToString()))
|
||
words += w;
|
||
}
|
||
|
||
if(isDefaultFont)
|
||
{
|
||
// 常用字
|
||
var textAsset = AssetDatabase.LoadAssetAtPath<TextAsset>(DevStrPath);
|
||
foreach (var w in textAsset.text)
|
||
{
|
||
if (!words.Contains(w.ToString()))
|
||
words += w;
|
||
}
|
||
|
||
// 中文配置
|
||
var text = LocalizationMenuTools.CatWordsFromLuaConfig(new List<string>(){Application.dataPath + "/Developer/lua/app/config/strings/cn"});
|
||
foreach (var w in text)
|
||
{
|
||
if (!words.Contains(w.ToString()))
|
||
words += w;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
static private void GetThaiWords(List<string> luaFolderPaths, out string words)
|
||
{
|
||
words = string.Empty;
|
||
//是否开发模式
|
||
var text = LocalizationMenuTools.CatWordsFromLuaConfig(new List<string>(){Application.dataPath + "/Developer/lua/app/config/strings/th"});
|
||
text += "ิ";
|
||
text += "ี";
|
||
text += "ึ";
|
||
text += "ื";
|
||
text += "ำ";
|
||
text += "ั";
|
||
text += "ํ";
|
||
|
||
text += "่";
|
||
text += "้";
|
||
text += "๊";
|
||
text += "๋";
|
||
foreach (var w in text)
|
||
{
|
||
if (!words.Contains(w.ToString()))
|
||
words += w;
|
||
}
|
||
}
|
||
|
||
static private void GenTMPFontAsset(Font font, TTFInfo ttfInfo, string assetName, bool isdevelop)
|
||
{
|
||
EditorUtility.DisplayProgressBar("生成TMP字体", "正在生成中...", 0f);
|
||
var assetDirPath = ttfInfo.fontFolder;
|
||
|
||
var assetPath = Path.Combine(assetDirPath, assetName);
|
||
var texturePath = assetPath.Replace(".asset", "_atlas.asset");
|
||
var matPath = assetPath.Replace(".asset", ".mat");
|
||
var fontAsset = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(assetPath);
|
||
if (!fontAsset)
|
||
{
|
||
if (!Directory.Exists(assetDirPath))
|
||
Directory.CreateDirectory(assetDirPath);
|
||
|
||
var targetSize = ttfInfo.atlasSize;
|
||
|
||
fontAsset = TMP_FontAsset.CreateFontAsset(font, FontSize, Padding, GRenderMode, targetSize, targetSize);
|
||
AssetDatabase.CreateAsset(fontAsset, assetPath);
|
||
|
||
var texture = fontAsset.atlasTextures[0];
|
||
texture.name = assetName.Replace(".asset", ".png");
|
||
if(File.Exists(texturePath))
|
||
{
|
||
File.Delete(texturePath);
|
||
}
|
||
AssetDatabase.CreateAsset(texture, texturePath);
|
||
fontAsset.atlasTextures[0] = AssetDatabase.LoadAssetAtPath<Texture2D>(texturePath);
|
||
|
||
var mat = fontAsset.material;
|
||
mat.name = assetName.Replace(".asset", ".mat");
|
||
if(File.Exists(matPath))
|
||
{
|
||
File.Delete(matPath);
|
||
}
|
||
AssetDatabase.CreateAsset(mat, matPath);
|
||
fontAsset.material = AssetDatabase.LoadAssetAtPath<Material>(matPath);
|
||
fontAsset.material.SetTexture(ShaderUtilities.ID_MainTex, texture);
|
||
fontAsset.material.SetFloat(ShaderUtilities.ID_TextureWidth, targetSize);
|
||
fontAsset.material.SetFloat(ShaderUtilities.ID_TextureHeight, targetSize);
|
||
fontAsset.material.SetFloat(ShaderUtilities.ID_GradientScale, Padding + 1);
|
||
|
||
fontAsset.ReadFontAssetDefinition();
|
||
}
|
||
else
|
||
{
|
||
fontAsset.atlasPopulationMode = AtlasPopulationMode.Dynamic; //设置成动态
|
||
AddSourceFontRef(assetPath, font);
|
||
UpdateFontAsset(fontAsset, font, assetDirPath, ttfInfo.atlasSize);
|
||
fontAsset.ClearFontAssetData();
|
||
EditorUtility.SetDirty(fontAsset);
|
||
}
|
||
|
||
// 泰语使用静态并特殊处理
|
||
if (assetName == AssetThaiName)
|
||
{
|
||
var luaFolderPaths = new List<string>();
|
||
luaFolderPaths.Add(Application.dataPath + "/Developer/lua/app/config/strings/th");
|
||
var words = string.Empty;
|
||
GetThaiWords(luaFolderPaths, out words);
|
||
Debug.Log("泰语字符集:" + words);
|
||
fontAsset.TryAddCharacters(words);
|
||
fontAsset.atlasPopulationMode = AtlasPopulationMode.Static;
|
||
// 修订部分重音位置
|
||
_Adjust(fontAsset);
|
||
}
|
||
|
||
if (null != fontAsset)
|
||
{
|
||
// DealWithMetric(fontAsset);
|
||
|
||
var fontssetPath = AssetDatabase.GetAssetPath(fontAsset);
|
||
AssetDatabase.ImportAsset(fontssetPath);
|
||
|
||
// DeleteSourceFontRef(fontssetPath);
|
||
fontAsset.fallbackFontAssetTable.Clear();
|
||
if(assetName == AssetDefaultName)
|
||
{
|
||
var fallbackAsset = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(Path.Combine(assetDirPath, AssetThaiName));
|
||
if (fallbackAsset != null)
|
||
{
|
||
fontAsset.fallbackFontAssetTable.Add(fallbackAsset);
|
||
}
|
||
fallbackAsset = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(Path.Combine(assetDirPath, AssetJaName));
|
||
if (fallbackAsset != null)
|
||
{
|
||
fontAsset.fallbackFontAssetTable.Add(fallbackAsset);
|
||
}
|
||
}
|
||
}
|
||
EditorUtility.ClearProgressBar();
|
||
}
|
||
|
||
static void DeleteSourceFontRef(string path)
|
||
{
|
||
var fontAsset = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(path);
|
||
if (fontAsset != null)
|
||
{
|
||
var assetInfo = new SerializedObject(fontAsset);
|
||
var property = assetInfo.FindProperty("m_SourceFontFileGUID");
|
||
property.stringValue = null;
|
||
var property2 = assetInfo.FindProperty("m_SourceFontFile_EditorRef");
|
||
property2.objectReferenceValue = null;
|
||
var property3 = assetInfo.FindProperty("m_SourceFontFile");
|
||
property3.objectReferenceValue = null;
|
||
assetInfo.ApplyModifiedProperties();
|
||
EditorUtility.SetDirty(fontAsset);
|
||
}
|
||
}
|
||
|
||
static void AddSourceFontRef(string path, Font font)
|
||
{
|
||
var fontAsset = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(path);
|
||
if (fontAsset != null)
|
||
{
|
||
string guid;
|
||
long localID;
|
||
UnityEditor.AssetDatabase.TryGetGUIDAndLocalFileIdentifier(font, out guid, out localID);
|
||
var assetInfo = new SerializedObject(fontAsset);
|
||
var property = assetInfo.FindProperty("m_SourceFontFileGUID");
|
||
property.stringValue = guid;
|
||
var property2 = assetInfo.FindProperty("m_SourceFontFile_EditorRef");
|
||
property2.objectReferenceValue = font;
|
||
var property3 = assetInfo.FindProperty("m_SourceFontFile");
|
||
property3.objectReferenceValue = font;
|
||
assetInfo.ApplyModifiedProperties();
|
||
}
|
||
}
|
||
|
||
static private void UpdateFontAsset(TMP_FontAsset fontAsset, Font font, string assetDirPath, int tarAtlasSize)
|
||
{
|
||
var targetSize = tarAtlasSize;
|
||
|
||
var oldFontSize = fontAsset.faceInfo.pointSize;
|
||
if (oldFontSize != FontSize)
|
||
{
|
||
FontEngine.LoadFontFace(font, FontSize);
|
||
var Type = fontAsset.GetType();
|
||
var f = Type.GetProperty("faceInfo");
|
||
f.SetValue(fontAsset, FontEngine.GetFaceInfo());
|
||
}
|
||
|
||
var altasSize = fontAsset.atlasWidth;
|
||
var altasPadding = fontAsset.atlasPadding;
|
||
if (altasSize != targetSize || altasPadding != Padding)
|
||
{
|
||
var Type = fontAsset.GetType();
|
||
var w = Type.GetProperty("atlasWidth");
|
||
w.SetValue(fontAsset, targetSize);
|
||
var h = Type.GetProperty("atlasHeight");
|
||
h.SetValue(fontAsset, targetSize);
|
||
var p = Type.GetProperty("atlasPadding");
|
||
p.SetValue(fontAsset, Padding);
|
||
|
||
fontAsset.material.SetFloat(ShaderUtilities.ID_TextureWidth, targetSize);
|
||
fontAsset.material.SetFloat(ShaderUtilities.ID_TextureHeight, targetSize);
|
||
fontAsset.material.SetFloat(ShaderUtilities.ID_GradientScale, Padding + 1);
|
||
}
|
||
|
||
//keep update
|
||
Material[] materialPresets = TMP_EditorUtility.FindMaterialReferences(fontAsset);
|
||
for (int i = 0; i < materialPresets.Length; i++)
|
||
{
|
||
Material mat = materialPresets[i];
|
||
var path = AssetDatabase.GetAssetPath(mat);
|
||
if (!path.Contains(assetDirPath))
|
||
continue;
|
||
BF.BFLog.Log("UpdateFontAsset material " + path);
|
||
mat.SetFloat(ShaderUtilities.ID_TextureWidth, targetSize);
|
||
mat.SetFloat(ShaderUtilities.ID_TextureHeight, targetSize);
|
||
mat.SetFloat(ShaderUtilities.ID_GradientScale, Padding + 1);
|
||
}
|
||
|
||
var renderMode = fontAsset.atlasRenderMode;
|
||
if (renderMode != GRenderMode)
|
||
{
|
||
var Type = fontAsset.GetType();
|
||
var r = Type.GetProperty("altasRenderMode");
|
||
r.SetValue(fontAsset, GRenderMode);
|
||
}
|
||
|
||
}
|
||
|
||
/// <summary>
|
||
/// 对于一些特定的字符进行布局调整
|
||
/// </summary>
|
||
/// <param name="fontAsset"></param>
|
||
static private void DealWithMetric(TMP_FontAsset fontAsset)
|
||
{
|
||
//数字"1"
|
||
if (fontAsset.characterLookupTable.ContainsKey(0x31))
|
||
{
|
||
var character = fontAsset.characterLookupTable[0x31];
|
||
var metrics = character.glyph.metrics;
|
||
metrics.horizontalBearingX = 4f;
|
||
metrics.horizontalAdvance = 19f;
|
||
character.glyph.metrics = metrics;
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
|
||
|
||
|
||
#region TransforFontAssets
|
||
|
||
/// <summary>
|
||
/// 设置所有prefab的FontAssets
|
||
/// </summary>
|
||
/// <param name="selectObj"></param>
|
||
/// <param name="assetPath"></param>
|
||
/// <param name="keepHierachy"></param>
|
||
static public void TransforAllFontAsset()
|
||
{
|
||
var filter = "Assets/prefabs/ui/";
|
||
string[] guids = AssetDatabase.FindAssets("t:prefab", new string[] { });
|
||
foreach (string guid in guids)
|
||
{
|
||
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||
if (assetPath.Contains(filter))
|
||
{
|
||
var obj = Object.Instantiate(AssetDatabase.LoadAssetAtPath<GameObject>(assetPath));
|
||
TransforFontAsset(obj, assetPath);
|
||
Object.DestroyImmediate(obj);
|
||
}
|
||
}
|
||
AssetDatabase.SaveAssets();
|
||
AssetDatabase.Refresh();
|
||
}
|
||
|
||
static private void TransforFontAsset(GameObject selectObj, string assetPath = "", bool keepHierachy = false)
|
||
{
|
||
if (null == selectObj)
|
||
return;
|
||
|
||
var fakeParent = EditorUtility.GetPrefabParent(selectObj);
|
||
var parent = PrefabUtility.GetNearestPrefabInstanceRoot(selectObj);
|
||
parent = parent == null ? selectObj : parent; //处理一层结构
|
||
assetPath = string.IsNullOrEmpty(assetPath) ? AssetDatabase.GetAssetPath(fakeParent) : assetPath;
|
||
var childPath = string.Empty;
|
||
BF.Utils.GetTransformPath(selectObj.transform, parent.transform, ref childPath);
|
||
var index = childPath.IndexOf("/");
|
||
childPath = childPath.Substring(index + 1, childPath.Length - index - 1);
|
||
|
||
var tmpComs = parent.GetComponentsInChildren<TextMeshProUGUI>(true);
|
||
if (null != tmpComs)
|
||
{
|
||
var replace = false;
|
||
foreach (var com in tmpComs)
|
||
{
|
||
string desPath = string.Empty;
|
||
string srcPath = AssetDatabase.GetAssetPath(com.font);
|
||
TMP_FontAsset targetFont;
|
||
|
||
targetFont = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(defaultFontPath);
|
||
|
||
if (targetFont && com.font != targetFont)
|
||
{
|
||
var matName = com.fontSharedMaterial.name;
|
||
var matPath = "";
|
||
|
||
targetFont = AssetDatabase.LoadAssetAtPath<TMP_FontAsset>(defaultFontPath);
|
||
matPath = "Assets/arts/fonts/tmpfonts/default/font/" + matName + ".mat";
|
||
|
||
var targetMat = AssetDatabase.LoadAssetAtPath<Material>(matPath);
|
||
|
||
com.font = targetFont;
|
||
if (targetMat)
|
||
{
|
||
com.fontSharedMaterial = targetMat;
|
||
replace = true;
|
||
}
|
||
}
|
||
}
|
||
|
||
if (replace)
|
||
{
|
||
Debug.Log("Font chg, prefab asset name = " + assetPath);
|
||
PrefabUtility.SaveAsPrefabAsset(parent, assetPath);
|
||
|
||
if (keepHierachy)
|
||
{
|
||
//重新替换下
|
||
var pParent = parent.transform.parent;
|
||
var pIndex = parent.transform.GetSiblingIndex();
|
||
UnityEngine.Object.DestroyImmediate(parent);
|
||
var prefab = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
|
||
var obj = PrefabUtility.InstantiatePrefab(prefab) as GameObject;
|
||
obj.transform.SetParent(pParent, false);
|
||
obj.transform.SetSiblingIndex(pIndex);
|
||
var go = obj.transform.Find(childPath);
|
||
Selection.activeObject = go;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
|
||
static public void RemoveTMPUISubMesh()
|
||
{
|
||
var filter = "Assets/prefabs/ui/";
|
||
string[] guids = AssetDatabase.FindAssets("t:prefab", new string[] { });
|
||
foreach (string guid in guids)
|
||
{
|
||
string assetPath = AssetDatabase.GUIDToAssetPath(guid);
|
||
if (assetPath.Contains(filter))
|
||
{
|
||
var gameObject = AssetDatabase.LoadAssetAtPath<GameObject>(assetPath);
|
||
var subMeshUIs = gameObject.GetComponentsInChildren<TMP_SubMeshUI>(true);
|
||
var beChecked = (null != subMeshUIs && subMeshUIs.Length > 0) ? true : false;
|
||
if (beChecked)
|
||
{
|
||
gameObject = Object.Instantiate(gameObject);
|
||
subMeshUIs = gameObject.GetComponentsInChildren<TMP_SubMeshUI>(true);
|
||
var len = subMeshUIs.Length;
|
||
for (int i = 0; i < len; i++)
|
||
{
|
||
var target = subMeshUIs[i].gameObject;
|
||
var tarParent = target.transform.parent;
|
||
if (tarParent && tarParent.GetComponent<TextMeshProUGUI>())
|
||
{
|
||
var childPath = string.Empty;
|
||
BF.Utils.GetTransformPath(target.transform, gameObject.transform, ref childPath);
|
||
BF.BFLog.Log("检查到字体图集没有包含!!!!!---------- {0}, 来源{1}", tarParent.GetComponent<TextMeshProUGUI>().text, childPath);
|
||
tarParent.GetComponent<TextMeshProUGUI>().text = "";
|
||
}
|
||
Object.DestroyImmediate(target);
|
||
}
|
||
|
||
var parent = PrefabUtility.GetNearestPrefabInstanceRoot(gameObject);
|
||
parent = parent == null ? gameObject : parent; //处理一层结构
|
||
PrefabUtility.SaveAsPrefabAsset(parent, assetPath);
|
||
AssetDatabase.SaveAssets();
|
||
AssetDatabase.Refresh();
|
||
Object.DestroyImmediate(gameObject);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
#endregion
|
||
|
||
// 针对泰语处理
|
||
static bool overrideAll = true;
|
||
static float wannayukHeight = 10f;
|
||
static float aumXPlacementAfter = -35f;
|
||
static float aumXPlacementBefore = 10f;
|
||
static void _Adjust(TMP_FontAsset fontAsset)
|
||
{
|
||
if (fontAsset == null)
|
||
{
|
||
Debug.Log("No FontAsset selected");
|
||
return;
|
||
}
|
||
|
||
var glyphPairAdjustmentRecords = new List<TMP_GlyphPairAdjustmentRecord>(fontAsset.fontFeatureTable.glyphPairAdjustmentRecords);
|
||
var lookupTable = fontAsset.characterLookupTable;
|
||
|
||
var glyphPairAdjustmentRecordLookupDictionary =
|
||
(Dictionary<uint, TMP_GlyphPairAdjustmentRecord>) fontAsset.fontFeatureTable
|
||
.GetType()
|
||
.GetField("m_GlyphPairAdjustmentRecordLookupDictionary", BindingFlags.NonPublic | BindingFlags.Instance)?
|
||
.GetValue(fontAsset.fontFeatureTable);
|
||
|
||
int[] saras = new int[7];
|
||
int[] wannayuks = new int[4];
|
||
|
||
//get sara
|
||
saras[0] = (int) lookupTable[GetUnicodeCharacter("ิ")].glyphIndex; // อิ
|
||
saras[1] = (int) lookupTable[GetUnicodeCharacter("ี")].glyphIndex; // อี
|
||
saras[2] = (int) lookupTable[GetUnicodeCharacter("ึ")].glyphIndex; // อึ
|
||
saras[3] = (int) lookupTable[GetUnicodeCharacter("ื")].glyphIndex; // อื
|
||
saras[4] = (int) lookupTable[GetUnicodeCharacter("ำ")].glyphIndex; // ำ
|
||
saras[5] = (int) lookupTable[GetUnicodeCharacter("ั")].glyphIndex; // ั
|
||
saras[6] = (int) lookupTable[GetUnicodeCharacter("ํ")].glyphIndex; // ํ
|
||
//get wanna yuk
|
||
wannayuks[0] = (int) lookupTable[GetUnicodeCharacter("่")].glyphIndex; //เอก
|
||
wannayuks[1] = (int) lookupTable[GetUnicodeCharacter("้")].glyphIndex; //โท
|
||
wannayuks[2] = (int) lookupTable[GetUnicodeCharacter("๊")].glyphIndex; //ตรี
|
||
wannayuks[3] = (int) lookupTable[GetUnicodeCharacter("๋")].glyphIndex; //จัตวา
|
||
int recordAdd = 0;
|
||
foreach (var sara in saras)
|
||
{
|
||
foreach (var wannayuk in wannayuks)
|
||
{
|
||
float xPlacement = sara == saras[4] || sara == saras[6] ? aumXPlacementAfter : 0;
|
||
|
||
TMP_GlyphValueRecord saraPosition = new TMP_GlyphValueRecord(0, 0, 0, 0);
|
||
TMP_GlyphAdjustmentRecord saraGlyph = new TMP_GlyphAdjustmentRecord((uint) sara, saraPosition);
|
||
|
||
TMP_GlyphValueRecord wannayukPosition = new TMP_GlyphValueRecord(xPlacement, wannayukHeight, 0, 0);
|
||
TMP_GlyphAdjustmentRecord wannayukGlyph = new TMP_GlyphAdjustmentRecord((uint) wannayuk, wannayukPosition);
|
||
|
||
var saraThenWannayukGlyphPair = new TMP_GlyphPairAdjustmentRecord(saraGlyph, wannayukGlyph);
|
||
|
||
if (sara == saras[4] || sara == saras[6])
|
||
{
|
||
xPlacement = aumXPlacementBefore;
|
||
wannayukPosition = new TMP_GlyphValueRecord(xPlacement, wannayukHeight, 0, 0);
|
||
wannayukGlyph = new TMP_GlyphAdjustmentRecord((uint) wannayuk, wannayukPosition);
|
||
}
|
||
|
||
var wannayukThenSaraGlyphPair = new TMP_GlyphPairAdjustmentRecord(wannayukGlyph, saraGlyph);
|
||
|
||
uint firstPairKey = saraThenWannayukGlyphPair.firstAdjustmentRecord.glyphIndex << 16 | saraThenWannayukGlyphPair.secondAdjustmentRecord.glyphIndex;
|
||
uint secondPairKey = wannayukThenSaraGlyphPair.firstAdjustmentRecord.glyphIndex << 16 | wannayukThenSaraGlyphPair.secondAdjustmentRecord.glyphIndex;
|
||
|
||
if (overrideAll)
|
||
{
|
||
glyphPairAdjustmentRecords.RemoveAll(record => IsGlyphPairEqual(record, saraThenWannayukGlyphPair) ||
|
||
IsGlyphPairEqual(record, wannayukThenSaraGlyphPair));
|
||
|
||
glyphPairAdjustmentRecords.Add(saraThenWannayukGlyphPair);
|
||
glyphPairAdjustmentRecords.Add(wannayukThenSaraGlyphPair);
|
||
|
||
if (glyphPairAdjustmentRecordLookupDictionary != null && !glyphPairAdjustmentRecordLookupDictionary.ContainsKey(firstPairKey))
|
||
{
|
||
glyphPairAdjustmentRecordLookupDictionary.Add(firstPairKey, saraThenWannayukGlyphPair);
|
||
}
|
||
|
||
recordAdd += 2;
|
||
}
|
||
else if (glyphPairAdjustmentRecordLookupDictionary != null)
|
||
{
|
||
if (!glyphPairAdjustmentRecordLookupDictionary.ContainsKey(firstPairKey))
|
||
{
|
||
glyphPairAdjustmentRecords.Add(saraThenWannayukGlyphPair);
|
||
recordAdd++;
|
||
}
|
||
|
||
if (!glyphPairAdjustmentRecordLookupDictionary.ContainsKey(secondPairKey))
|
||
{
|
||
glyphPairAdjustmentRecords.Add(wannayukThenSaraGlyphPair);
|
||
recordAdd++;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (recordAdd > 0)
|
||
{
|
||
fontAsset.fontFeatureTable.glyphPairAdjustmentRecords = glyphPairAdjustmentRecords;
|
||
fontAsset.fontFeatureTable.SortGlyphPairAdjustmentRecords();
|
||
EditorUtility.SetDirty(fontAsset);
|
||
AssetDatabase.SaveAssets();
|
||
Canvas.ForceUpdateCanvases();
|
||
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
|
||
}
|
||
|
||
Debug.Log("Adjust font : <color=#2bcaff>" + fontAsset.name + "</color>" +
|
||
" Height offset : <color=#d8ff2b>" + wannayukHeight + "</color>" +
|
||
" Number of adjustment add : <color=#5dfa41>" + recordAdd + "</color>");
|
||
}
|
||
|
||
static void _Clear(TMP_FontAsset fontAsset)
|
||
{
|
||
fontAsset.fontFeatureTable.glyphPairAdjustmentRecords = new List<TMP_GlyphPairAdjustmentRecord>();
|
||
EditorUtility.SetDirty(fontAsset);
|
||
AssetDatabase.SaveAssets();
|
||
Canvas.ForceUpdateCanvases();
|
||
UnityEditorInternal.InternalEditorUtility.RepaintAllViews();
|
||
}
|
||
|
||
static uint GetUnicodeCharacter (string source)
|
||
{
|
||
uint unicode;
|
||
|
||
if (source.Length == 1)
|
||
unicode = source[0];
|
||
else if (source.Length == 6)
|
||
unicode = (uint)TMP_TextUtilities.StringHexToInt(source.Replace("\\u", ""));
|
||
else
|
||
unicode = (uint)TMP_TextUtilities.StringHexToInt(source.Replace("\\U", ""));
|
||
|
||
return unicode;
|
||
}
|
||
|
||
static bool IsGlyphPairEqual(TMP_GlyphPairAdjustmentRecord a, TMP_GlyphPairAdjustmentRecord b)
|
||
{
|
||
return a.firstAdjustmentRecord.glyphIndex == b.firstAdjustmentRecord.glyphIndex &&
|
||
a.secondAdjustmentRecord.glyphIndex == b.secondAdjustmentRecord.glyphIndex;
|
||
}
|
||
|
||
}
|
||
|
||
}
|