123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153 |
- using System.Collections.Generic;
- using System.IO;
- using System.Text.RegularExpressions;
- using UnityEditor;
- using UnityEngine;
- // 创建bmfont
- namespace FL.Editor
- {
- public class BMFontCreator
- {
- [MenuItem("Assets/Create/XGame/CreateBMFont")]
- static void Create()
- {
- var creator = new BMFontCreator();
- creator.Start();
- }
- private void Start()
- {
- var obj = Selection.activeObject;
- string fntPath = AssetDatabase.GetAssetPath(obj);
- if (fntPath.IndexOf(".fnt") == -1)
- {
- // 不是字体文件
- Debug.LogError("请先选择一个*.fnt!");
- return;
- }
- //if (!File.Exists(customFontPath))
- //{
- // Debug.LogError("The .fontsettings file not exists");
- // return;
- //}
- Debug.Log(fntPath);
- using var reader = new StreamReader(new FileStream(fntPath, FileMode.Open));
- var charInfos = new List<CharacterInfo>();
- var reg = new Regex(@"char id=(?<id>\d+)\s+x=(?<x>\d+)\s+y=(?<y>\d+)\s+width=(?<width>\d+)\s+height=(?<height>\d+)\s+xoffset=(?<xoffset>(-|\d)+)\s+yoffset=(?<yoffset>(-|\d)+)\s+xadvance=(?<xadvance>\d+)\s+");
- string line = reader.ReadLine();
- int lineHeight = 65;
- int texWidth = 512;
- int texHeight = 512;
- var pngName = "";
- while (line != null)
- {
- if (line.IndexOf("char id=") != -1)
- {
- var match = reg.Match(line);
- if (match.Success)
- {
- var id = System.Convert.ToInt32(match.Groups["id"].Value);
- var x = System.Convert.ToInt32(match.Groups["x"].Value);
- var y = System.Convert.ToInt32(match.Groups["y"].Value);
- var width = System.Convert.ToInt32(match.Groups["width"].Value);
- var height = System.Convert.ToInt32(match.Groups["height"].Value);
- var xoffset = System.Convert.ToInt32(match.Groups["xoffset"].Value);
- var yoffset = System.Convert.ToInt32(match.Groups["yoffset"].Value);
- var xadvance = System.Convert.ToInt32(match.Groups["xadvance"].Value);
- Debug.Log($"字符:{(char)id} id:{id} width:{width} height:{height}");
- if (height > lineHeight)
- lineHeight = height;
- var info = new CharacterInfo
- {
- index = id
- };
- //uv左下角(0,0)->右上角(1,1)
- float uvx = 1f * x / texWidth;
- float uvy = 1 - (1f * y / texHeight);
- float uvw = 1f * width / texWidth;
- float uvh = 1f * height / texHeight;
- info.uvBottomLeft = new Vector2(uvx, uvy - uvh);
- info.uvBottomRight = new Vector2(uvx + uvw, uvy - uvh);
- info.uvTopLeft = new Vector2(uvx, uvy);
- info.uvTopRight = new Vector2(uvx + uvw, uvy);
- info.minX = xoffset;
- //glyphHeight赋值时内部会加上高度,需要提前减掉高度
- //文本上对齐时: - height,居中对其时: - height / 2
- //下对齐时不用减
- info.minY = yoffset - height / 2;
- info.glyphWidth = width;
- info.glyphHeight = height;
- info.advance = xadvance;
- //info.size = 18;
- //info.style = FontStyle.Italic;
- charInfos.Add(info);
- }
- }
- else if (line.IndexOf("scaleW=") != -1)
- {
- var reg2 = new Regex(@"common lineHeight=(?<lineHeight>\d+)\s+.*scaleW=(?<scaleW>\d+)\s+scaleH=(?<scaleH>\d+)");
- var match = reg2.Match(line);
- if (match.Success)
- {
- lineHeight = System.Convert.ToInt32(match.Groups["lineHeight"].Value);
- texWidth = System.Convert.ToInt32(match.Groups["scaleW"].Value);
- texHeight = System.Convert.ToInt32(match.Groups["scaleH"].Value);
- }
- }
- else if (line.IndexOf("file=") != -1)
- {
- var match = Regex.Match(line, @"\s+.*file=""(.+?)""");
- if (match.Success)
- {
- pngName = match.Groups[1].Value;
- }
- }
- line = reader.ReadLine();
- }
- Debug.Log($"字体贴图 Name:{pngName} Width:{texWidth} Height:{texHeight} ");
- if (string.IsNullOrEmpty(pngName))
- {
- Debug.LogError($"字体贴图名字为空, 请检查*.fnt文件.");
- return;
- }
- var texturePath = Path.Combine(Path.GetDirectoryName(fntPath), pngName);
- var texture = AssetDatabase.LoadAssetAtPath<Texture>(texturePath);
- if (texture == null)
- {
- Debug.LogError($"找不到字体贴图. Path:{texturePath}");
- return;
- }
- var customFontPath = fntPath.Replace(".fnt", ".fontsettings");
- var customFont = AssetDatabase.LoadAssetAtPath<Font>(customFontPath);
- if (customFont == null)
- {
- customFont = new Font(Path.GetFileNameWithoutExtension(fntPath));
- AssetDatabase.CreateAsset(customFont, customFontPath);
- }
- var matiralPath = fntPath.Replace(".fnt", ".mat");
- var material = AssetDatabase.LoadAssetAtPath<Material>(matiralPath);
- if (material == null)
- {
- material = new Material(Shader.Find("XGame/Text Shader"));
- AssetDatabase.CreateAsset(material, matiralPath);
- }
- material.mainTexture = texture;
- customFont.material = material;
- customFont.characterInfo = charInfos.ToArray();
- EditorUtility.SetDirty(material);
- EditorUtility.SetDirty(customFont);
- AssetDatabase.SaveAssets();
- AssetDatabase.Refresh();
- if (customFont.lineHeight < lineHeight)
- {
- Debug.LogWarning($"需要手动修改字体的LineSpacing. 当前:{customFont.lineHeight} 推荐:{lineHeight}");
- }
- Debug.Log($"字体生成完成. Path:{customFontPath}");
- }
- }
- }
|