UGUI中CustomFont(BMFont)字体使用与制作¶
首先使用工具Bitmap Font Generator生成.fnt和图集贴图,教程参考Unity3D-使用Bitmap Font Generator自定义字体 这里主要介绍根据Text格式的.fnt和贴图 在unity中自定义字体
- 生成字体教程 上代码(Unity版本5.6.0f3) 生成字体文件后必须重启unity才能生效,否则字体文件不能正确加载(unity bug或者我没找到方法刷新unity,知道的请指教) 将脚本放在Unity工程的Editor目录下 点击Tools→BMFontTools按钮
using UnityEngine; using UnityEditor; using System.Collections.Generic; public class BMFontEditor : EditorWindow { public TextAsset fontPosTbl; public Texture fontTexture; public Vector2 scrollPos; struct ChrRect { public int id; public int x; public int y; public int w; public int h; public int xofs; public int yofs; public int index; public float uvX; public float uvY; public float uvW; public float uvH; public float vertX; public float vertY; public float vertW; public float vertH; public float width; } // add menu [MenuItem("Tools/BMFontTools")] static void Init() { EditorWindow.GetWindow(typeof(BMFontEditor)); } // layout window void OnGUI() { //EditorGUILayout.BeginScrollView(scrollPos); EditorGUILayout.BeginVertical(); // use .fnt(.txt) fontTexture = (Texture)EditorGUILayout.ObjectField("Font Texture", fontTexture, typeof(Texture), false); EditorGUILayout.Space(); EditorGUILayout.LabelField("Use BMFont fnt File", EditorStyles.boldLabel); EditorGUILayout.LabelField("(must Font Descriptor select Text)", EditorStyles.boldLabel); fontPosTbl = (TextAsset)EditorGUILayout.ObjectField("BMFont fnt (.fnt)", fontPosTbl, typeof(TextAsset), false); if (GUILayout.Button("Create(创建后必须重启生效)")) { if (fontTexture == null) this.ShowNotification(new GUIContent("No Font Texture selected")); else if (fontPosTbl == null) this.ShowNotification(new GUIContent("No Font Position Table file selected")); else { CalcChrRect(fontPosTbl, fontTexture); } } EditorGUILayout.LabelField("(Must Restart unity valid!)", EditorStyles.whiteBoldLabel); EditorGUILayout.LabelField("*********************************", EditorStyles.largeLabel); EditorGUILayout.EndVertical(); //EditorGUILayout.EndScrollView(); } void OnInspectorUpdate() { this.Repaint(); } void CalcChrRect(TextAsset posTbl, Texture tex) { string fileName = AssetDatabase.GetAssetPath(fontPosTbl); string texName = AssetDatabase.GetAssetPath(tex); string fontName = System.IO.Path.GetFileNameWithoutExtension(fileName); string fontPath = fileName.Replace(".fnt", ".fontsettings"); string matPath = fileName.Replace(".fnt", ".mat"); float imgw = (float)tex.width; float imgh = (float)tex.height; string txt = posTbl.text; List<ChrRect> tblList = new List<ChrRect>(); foreach (string line in txt.Split('\n')) { if (line.IndexOf("char id=") == 0) { ChrRect d = GetChrRect(line, imgw, imgh); tblList.Add(d); } } if(tblList.Count==0) { new GUIContent("Failed"); return; } ChrRect[] tbls = tblList.ToArray(); Font font = new Font(); font.name = fontName; SetCharacterInfo(tbls, font); Material mat = new Material(Shader.Find("Unlit/Transparent")); mat.mainTexture = tex; mat.name = fontName; font.material = mat; Debug.Log(System.IO.Path.GetFileNameWithoutExtension(fileName)); Debug.Log(fileName); AssetDatabase.CreateAsset(mat, matPath); AssetDatabase.CreateAsset(font, fontPath); AssetDatabase.SaveAssets(); this.ShowNotification(new GUIContent("Complete")); AssetDatabase.Refresh(ImportAssetOptions.ForceUpdate); } // over write custom font by new CharacterInfo void SetCharacterInfo(ChrRect[] tbls, Font fontObj) { CharacterInfo[] nci = new CharacterInfo[tbls.Length]; for (int i = 0; i < tbls.Length; i++) { nci[i].index = tbls[i].index; nci[i].advance = (int)tbls[i].width; nci[i].uv.x = tbls[i].uvX; nci[i].uv.y = tbls[i].uvY; nci[i].uv.width = tbls[i].uvW; nci[i].uv.height = tbls[i].uvH; nci[i].vert.x = tbls[i].vertX; nci[i].vert.y = tbls[i].vertY; nci[i].vert.width = tbls[i].vertW; nci[i].vert.height = tbls[i].vertH; } fontObj.characterInfo = nci; } // get font table one line. ChrRect GetChrRect(string line, float imgw, float imgh) { ChrRect d = new ChrRect(); foreach (string s in line.Split(' ')) { if (s.IndexOf("id=") >= 0) d.id = GetParamInt(s, "id="); else if (s.IndexOf("x=") >= 0) d.x = GetParamInt(s, "x="); else if (s.IndexOf("y=") >= 0) d.y = GetParamInt(s, "y="); else if (s.IndexOf("width=") >= 0) d.w = GetParamInt(s, "width="); else if (s.IndexOf("height=") >= 0) d.h = GetParamInt(s, "height="); else if (s.IndexOf("xoffset=") >= 0) d.xofs = GetParamInt(s, "xoffset="); else if (s.IndexOf("yoffset=") >= 0) d.yofs = GetParamInt(s, "yoffset="); else if (s.IndexOf("xadvance=") >= 0) d.width = GetParamInt(s, "xadvance="); } d.index = d.id; d.uvX = (float)d.x / imgw; d.uvY = (float)(imgh-(d.y)) / imgh; d.uvW = (float)d.w / imgw; //d.uvH = (float)-d.h / imgh; d.uvH = (float)-d.h / imgh; d.vertX = (float)d.xofs; d.vertY = (float)d.yofs; d.vertW = d.w; d.vertH = d.h; return d; } // "wd=int" to int int GetParamInt(string s, string wd) { if (s.IndexOf(wd) >= 0) { int v; if (int.TryParse(s.Substring(wd.Length), out v)) return v; } return int.MaxValue; } }
打开界面
托入资源,.fnt文件必须是Text文本结构的,不能是Xml和Binary(Bitmap Font Generator在这里面配置)
点击生成
生成后必须重启unity才能生效,否则字体文件不能正确加载(unity bug或者我没找到方法刷新unity) **
- 文字换行问题 设置字体的LineSpacing属性,为文字的高度,这里设置应该是128,一般不用





