458 lines
15 KiB
C#
458 lines
15 KiB
C#
using UnityEngine;
|
|
using UnityEngine.UI;
|
|
using System.Collections;
|
|
using System.IO;
|
|
using System.Collections.Generic;
|
|
using UnityEditor;
|
|
using UnityEditorInternal;
|
|
using System.Text.RegularExpressions;
|
|
using Newtonsoft.Json;
|
|
using System.Linq;
|
|
using System;
|
|
|
|
namespace zbitmapfont
|
|
{
|
|
public class BitmapFontTool
|
|
{
|
|
[MenuItem("Assets/zbitmapfont/Rename")]
|
|
public static void Rename()
|
|
{
|
|
foreach (var a in Selection.assetGUIDs)
|
|
{
|
|
var p = AssetDatabase.GUIDToAssetPath(a);
|
|
if (!System.IO.File.Exists(p))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
var f = System.IO.Path.GetFileNameWithoutExtension(p);
|
|
var c = ConvertToChar(f);
|
|
InputDialog.ShowWindow(c.ToString(), (a) =>
|
|
{
|
|
if (string.IsNullOrEmpty(a))
|
|
{
|
|
return;
|
|
}
|
|
|
|
a = ConvertToFileName(a[0]);
|
|
string b = $"{System.IO.Path.GetDirectoryName(p)}/{a}{System.IO.Path.GetExtension(p)}";
|
|
if (System.IO.File.Exists(b))
|
|
{
|
|
Debug.LogError("file existed: " + b);
|
|
return;
|
|
}
|
|
|
|
System.IO.File.Move(p, b);
|
|
System.IO.File.Move(p + ".meta", b + ".meta");
|
|
|
|
AssetDatabase.Refresh();
|
|
});
|
|
break;
|
|
}
|
|
|
|
|
|
AssetDatabase.Refresh();
|
|
}
|
|
|
|
[MenuItem("Assets/zbitmapfont/CreateBitmapFont")]
|
|
public static void CreateBitmapFont()
|
|
{
|
|
foreach (var a in Selection.assetGUIDs)
|
|
{
|
|
var p = AssetDatabase.GUIDToAssetPath(a);
|
|
if (!System.IO.Directory.Exists(p))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
string destPath = p;
|
|
if (!CreateBitmapFont(p, destPath))
|
|
{
|
|
throw new System.Exception("CreateBitmapFont failed: " + p);
|
|
}
|
|
}
|
|
|
|
|
|
AssetDatabase.Refresh();
|
|
}
|
|
|
|
[MenuItem("Assets/zbitmapfont/CreateFontAsset")]
|
|
public static void CreateFontAsset()
|
|
{
|
|
foreach (var a in Selection.assetGUIDs)
|
|
{
|
|
var p = AssetDatabase.GUIDToAssetPath(a);
|
|
if (!System.IO.Directory.Exists(p))
|
|
{
|
|
continue;
|
|
}
|
|
|
|
string destPath = p;
|
|
if (!CreateBitmapFont(p, destPath))
|
|
{
|
|
throw new System.Exception("CreateBitmapFont failed: " + p);
|
|
}
|
|
CreateBitmapFontMaterial(destPath);
|
|
CreateFontAsset(destPath);
|
|
}
|
|
|
|
|
|
AssetDatabase.Refresh();
|
|
}
|
|
|
|
public static string GetCurrentScriptPath()
|
|
{
|
|
System.Diagnostics.StackTrace stackTrace = new System.Diagnostics.StackTrace(true);
|
|
System.Diagnostics.StackFrame frame = stackTrace.GetFrame(0);
|
|
string filePath = frame.GetFileName();
|
|
return filePath;
|
|
}
|
|
|
|
static char ConvertToChar(string fileName)
|
|
{
|
|
char index = fileName[0];
|
|
try
|
|
{
|
|
if (fileName.Length == 4)
|
|
{
|
|
int temp = System.Convert.ToInt32(fileName, 16);
|
|
index = (char)temp;
|
|
}
|
|
else if (fileName.Length > 1 && fileName[1] == '_')
|
|
{
|
|
if (fileName[0] == '_')
|
|
{
|
|
index = ' ';
|
|
}
|
|
else
|
|
{
|
|
index = (char)('A' - 'a' + index);
|
|
}
|
|
}
|
|
}
|
|
catch (Exception e) { }
|
|
|
|
return index;
|
|
}
|
|
|
|
static string ConvertToFileName(char c)
|
|
{
|
|
string fileName = c.ToString();
|
|
try
|
|
{
|
|
if (System.IO.Path.GetInvalidFileNameChars().Contains(c))
|
|
{
|
|
fileName = ((int)c).ToString("x4");
|
|
}
|
|
else if (c == ' ')
|
|
{
|
|
return "__";
|
|
}
|
|
else if (c >= 'A' && c <= 'Z')
|
|
{
|
|
fileName = (char)(c - 'A' + 'a') + "_";
|
|
}
|
|
}
|
|
catch (Exception e) { }
|
|
|
|
return fileName;
|
|
}
|
|
|
|
public static bool CreateBitmapFont(string srcPath, string destPath)
|
|
{
|
|
destPath = System.IO.Path.GetFullPath(destPath);
|
|
|
|
var paths = System.IO.Directory.GetFiles(srcPath, "*.png", SearchOption.TopDirectoryOnly);
|
|
List<int> chars = new();
|
|
List<string> icons = new();
|
|
|
|
var sumSize = 0;
|
|
foreach (var path in paths)
|
|
{
|
|
var fileName = Path.GetFileNameWithoutExtension(path);
|
|
|
|
int index = ConvertToChar(fileName);
|
|
|
|
//int index = fileName[0];
|
|
|
|
|
|
//if (fileName.Length == 4)
|
|
//{
|
|
// int temp = System.Convert.ToInt32(fileName, 16);
|
|
// index = (char)temp;
|
|
//}
|
|
//else if (fileName.Length > 1 && fileName[1] == '_')
|
|
//{
|
|
// if (fileName[0] == '_')
|
|
// {
|
|
// index = ' ';
|
|
// }
|
|
// else
|
|
// {
|
|
// index = (char)('A' - 'a' + index);
|
|
// }
|
|
//}
|
|
|
|
chars.Add(index);
|
|
icons.Add($"icon=\"{System.IO.Path.GetFullPath(path)}\",{index},0,0,0");
|
|
|
|
|
|
var tex = AssetDatabase.LoadAssetAtPath<Texture2D>(path);
|
|
sumSize += tex.width * tex.height;
|
|
|
|
}
|
|
|
|
var pngWidth = Mathf.Pow(2, Mathf.CeilToInt(Mathf.Log(Mathf.Sqrt(sumSize), 2)));
|
|
//var pngWidth = Mathf.CeilToInt(Mathf.Sqrt(sumSize));
|
|
|
|
|
|
var templateConfigStr = System.IO.File.ReadAllText($"{System.IO.Path.GetDirectoryName(GetCurrentScriptPath())}/../template.bmfc");
|
|
|
|
|
|
|
|
|
|
for (; pngWidth <= 4096; pngWidth *= 2)
|
|
{
|
|
var configStr = string.Format(templateConfigStr, string.Join(",", chars), string.Join("\n", icons), pngWidth, pngWidth);
|
|
|
|
var tempPath = $"{destPath}.bmfc";
|
|
|
|
System.IO.File.WriteAllText(tempPath, configStr);
|
|
|
|
|
|
var exePath = $"{System.IO.Path.GetDirectoryName(GetCurrentScriptPath())}/../bmfont1.14a~/bmfont64.com";
|
|
var param = $"-c \"{tempPath}\" -o \"{destPath}\"";
|
|
|
|
|
|
var ret = CommandLineTool.RunCommand2(exePath, param, Application.dataPath);
|
|
|
|
if (ret.ExitCode != 0)
|
|
{
|
|
Debug.LogError(ret.StdErr);
|
|
Debug.LogError(ret.StdOut);
|
|
}
|
|
else
|
|
{
|
|
int count = 0;
|
|
for (int i = 0; true; i++)
|
|
{
|
|
var pngPath = $"{destPath}_{i}.png";
|
|
if (!System.IO.File.Exists(pngPath))
|
|
{
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
if (i > 0)
|
|
{
|
|
System.IO.File.Delete(pngPath);
|
|
}
|
|
}
|
|
count++;
|
|
}
|
|
|
|
if (count <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (count == 1)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
AssetDatabase.Refresh();
|
|
|
|
{
|
|
var pngPath = System.IO.Path.GetRelativePath(System.IO.Path.GetDirectoryName(Application.dataPath), $"{destPath}_0.png");
|
|
var importer = TextureImporter.GetAtPath(pngPath) as TextureImporter;
|
|
importer.mipmapEnabled = false;
|
|
importer.alphaIsTransparency = true;
|
|
importer.npotScale = TextureImporterNPOTScale.None;
|
|
importer.SaveAndReimport();
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static void CreateBitmapFontMaterial(string destPath)
|
|
{
|
|
string pngPath = destPath + "_0.png";
|
|
Texture2D tex = AssetDatabase.LoadAssetAtPath(pngPath, typeof(Texture2D)) as Texture2D;
|
|
|
|
Shader shader = Shader.Find("UI/Default");
|
|
Material material = new Material(shader);
|
|
material.mainTexture = tex;
|
|
AssetDatabase.CreateAsset(material, destPath + ".mat");
|
|
|
|
AssetDatabase.Refresh();
|
|
}
|
|
|
|
|
|
|
|
|
|
static void CreateFontAsset(string bitmapfontPath)
|
|
{
|
|
var fntPath = $"{bitmapfontPath}.fnt";
|
|
var pngPath = $"{bitmapfontPath}_0.png";
|
|
var matPath = $"{bitmapfontPath}.mat";
|
|
|
|
Material mat = AssetDatabase.LoadAssetAtPath(matPath, typeof(Material)) as Material;
|
|
Texture2D tex = AssetDatabase.LoadAssetAtPath(pngPath, typeof(Texture2D)) as Texture2D;
|
|
|
|
var fntConfigStr = System.IO.File.ReadAllText(fntPath);
|
|
StringReader sr = new StringReader(fntConfigStr);
|
|
|
|
List<string> charStrs = new();
|
|
|
|
while (true)
|
|
{
|
|
var line = sr.ReadLine();
|
|
if (string.IsNullOrEmpty(line))
|
|
{
|
|
break;
|
|
}
|
|
|
|
if (line.StartsWith("char "))
|
|
{
|
|
charStrs.Add(line);
|
|
|
|
|
|
}
|
|
}
|
|
|
|
CharacterInfo[] charInfos = new CharacterInfo[charStrs.Count];
|
|
|
|
|
|
float fontSize = 0;
|
|
|
|
for (int j = 0; j < charStrs.Count; j++)
|
|
{
|
|
var cStr = charStrs[j];
|
|
|
|
Dictionary<string, int> charparams = new();
|
|
var splitedStrings = cStr.Split(' ');
|
|
foreach (var a in splitedStrings)
|
|
{
|
|
if (a.Contains('='))
|
|
{
|
|
var b = a.Split('=');
|
|
var key = b[0];
|
|
var value = b[1];
|
|
charparams.Add(key, int.Parse(value));
|
|
}
|
|
}
|
|
|
|
int index = charparams["id"];
|
|
|
|
|
|
CharacterInfo charInfo = new CharacterInfo();
|
|
charInfo.index = index;
|
|
charInfo.advance = charparams["width"];
|
|
{
|
|
Rect r = new Rect();
|
|
r.x = (float)charparams["x"] / tex.width;
|
|
//r.y = (float)(tex.height - charparams["y"] - charparams["height"]) / tex.height;
|
|
r.y = (float)(tex.height - charparams["y"]) / tex.height;
|
|
r.width = (float)charparams["width"] / tex.width;
|
|
r.height = -(float)charparams["height"] / tex.height;
|
|
|
|
|
|
charInfo.uvBottomLeft = new Vector2(r.x, r.y);
|
|
charInfo.uvBottomRight = new Vector2(r.x + r.width, r.y);
|
|
charInfo.uvTopLeft = new Vector2(r.x, r.y + r.height);
|
|
charInfo.uvTopRight = new Vector2(r.x + r.width, r.y + r.height);
|
|
|
|
charInfo.minX = 0;
|
|
charInfo.minY = charparams["height"] / 2;
|
|
charInfo.maxX = charparams["width"];
|
|
charInfo.maxY = -charparams["height"] / 2;
|
|
|
|
charInfo.advance = charparams["xadvance"];
|
|
|
|
fontSize = charparams["height"];
|
|
}
|
|
|
|
//{
|
|
// Vector4 padding = TextureTool.getSpritePadding(info.pivot, info.rect, 1, sprite.rect);
|
|
// Rect r = new Rect();
|
|
// r.x = padding[0];
|
|
// r.y = padding[3];
|
|
// r.width = info.rect.width;
|
|
// r.height = info.rect.height;
|
|
// r.y = -r.y;
|
|
// r.height = -r.height;
|
|
// charInfo.vert = r;
|
|
|
|
// fontSize = info.rect.height + Mathf.Abs(padding[1]) + Mathf.Abs(padding[3]);
|
|
//}
|
|
charInfos[j] = charInfo;
|
|
}
|
|
|
|
string fontPath = bitmapfontPath + ".fontsettings";
|
|
|
|
Font font = null;
|
|
if (System.IO.File.Exists(fontPath))
|
|
{
|
|
font = AssetDatabase.LoadAssetAtPath<Font>(fontPath);
|
|
}
|
|
else
|
|
{
|
|
font = new Font();
|
|
}
|
|
|
|
font.material = mat;
|
|
font.name = System.IO.Path.GetFileName(bitmapfontPath);
|
|
font.characterInfo = charInfos;
|
|
|
|
|
|
|
|
|
|
string metaStr = null;
|
|
if (System.IO.File.Exists(fontPath + ".meta"))
|
|
{
|
|
metaStr = System.IO.File.ReadAllText(fontPath + ".meta");
|
|
}
|
|
|
|
if (System.IO.File.Exists(fontPath))
|
|
{
|
|
AssetDatabase.SaveAssets();
|
|
// System.IO.File.Delete(fontPath);
|
|
// AssetDatabase.Refresh();
|
|
}
|
|
else
|
|
{
|
|
AssetDatabase.CreateAsset(font, fontPath);
|
|
}
|
|
|
|
|
|
|
|
AssetDatabase.Refresh();
|
|
|
|
if (!string.IsNullOrEmpty(metaStr))
|
|
{
|
|
System.IO.File.WriteAllText(fontPath + ".meta", metaStr);
|
|
}
|
|
|
|
// string content = File.ReadAllText(fontPath);
|
|
//content = Regex.Replace(content, "(\\s+m_LineSpacing:\\s*)(.*)", "${1}" + fontSize);
|
|
//content = Regex.Replace(content, "(\\s+m_FontSize:\\s*)(.*)", "${1}" + fontSize);
|
|
//System.IO.File.WriteAllText(fontPath, content);
|
|
//AssetDatabase.ImportAsset(fontPath);
|
|
|
|
SerializedObject serializedFont = new SerializedObject(font);
|
|
SerializedProperty serializedLineSpacing = serializedFont.FindProperty("m_LineSpacing");
|
|
serializedLineSpacing.floatValue = fontSize;
|
|
SerializedProperty serializedFontSize = serializedFont.FindProperty("m_FontSize");
|
|
serializedFontSize.floatValue = fontSize;
|
|
SerializedProperty serializedAscent = serializedFont.FindProperty("m_Ascent");
|
|
serializedAscent.floatValue = fontSize / 2;
|
|
SerializedProperty serializedDescent = serializedFont.FindProperty("m_Descent");
|
|
serializedDescent.floatValue = -fontSize / 2;
|
|
serializedFont.ApplyModifiedProperties();
|
|
}
|
|
|
|
}
|
|
} |