Unity BMFont自定义字体
Unity中,使用位圖字體工具BMFont從圖片生成自定義字體流程
一、首先下載BMFont工具并安裝:http://www.angelcode.com/products/bmfont/
二、使用BMFont工具制作字體庫
1、先做一些設定:"Options"->“Export options”
寬度設置為所有素材寬度總和,高度為素材的高度(長和寬可以設置得稍微大一點,注意不要大太多),位深設置為32,輸出描述為XML格式,輸出圖片為PNG。
2、點擊"Edit"->"Open Image Manager",打開圖片導入界面:
3、點擊"Image"->"Import image...":
導入圖片,填寫圖片的ID,如這里導入的是0,把鼠標放到0的位置就會顯示0的AscII是48。按上述方法,依次加入其它字符的圖片,然后關閉Image Manager彈窗。
4、導出圖片,導出之前可以先點擊"Options"->"Visualize"預覽一下:
導出之前,點擊"Edit"->"(Un)Select all chars",取消選擇所有字符,避免將不需要的字符也導出來。最后點擊"Options"->"Save bitmap font as..."導出字體。將生成的.fnt及.png復制到項目中,接下來開始制作字體。
三、制作字體
工程中添加制作字體的腳本:
public class BMFont : EditorWindow {private TextAsset _fontTextAsset;private Texture _fontTexture;private string _fontsDir;[MenuItem("FontTools/BMFont", false, 12)]private static void BMFontTools(){BMFont bmFont = new BMFont();bmFont.Show();}private string _getAssetPath(string path){string pathTemp = path.Replace("\\", "/");pathTemp = pathTemp.Replace(Application.dataPath, "Assets");return pathTemp;}void OnGUI(){EditorGUILayout.BeginVertical();TextAsset taTemp = EditorGUILayout.ObjectField("選擇Font文件:", _fontTextAsset, typeof(TextAsset), true) as TextAsset;if (taTemp != _fontTextAsset && taTemp != null){string assetDir = Directory.GetParent(AssetDatabase.GetAssetPath(taTemp)).FullName;assetDir = _getAssetPath(assetDir);string imgPath = string.Format("{0}/{1}_0.png", assetDir, taTemp.name);_fontTexture = AssetDatabase.LoadAssetAtPath<Texture>(imgPath);_fontsDir = string.Format("{0}.fontsettings", Path.Combine(assetDir, taTemp.name));if (_fontTexture == null){_fontsDir = string.Empty;Debug.LogError(string.Format("未發現{0}文件", imgPath));}}_fontTextAsset = taTemp;_fontTexture = EditorGUILayout.ObjectField("選擇Font圖片文件:", _fontTexture, typeof(Texture), true) as Texture;GUI.enabled = false;_fontsDir = EditorGUILayout.TextField("字體生成路徑:", _fontsDir);GUI.enabled = true;if (GUILayout.Button("Generate Font")){if (!string.IsNullOrEmpty(_fontsDir)){Material mat = AssetDatabase.LoadAssetAtPath<Material>(_fontsDir.Replace(".fontsettings", ".mat"));if (mat == null){mat = new Material(Shader.Find("UI/Default Font"));AssetDatabase.CreateAsset(mat, _fontsDir.Replace(".fontsettings", ".mat"));}if (_fontTexture != null){mat = AssetDatabase.LoadAssetAtPath<Material>(_fontsDir.Replace(".fontsettings", ".mat"));mat.SetTexture("_MainTex", _fontTexture);}else{Debug.LogError("貼圖未做配置,請檢查配置");return;}Font font = AssetDatabase.LoadAssetAtPath<Font>(_fontsDir);if (font == null){font = new Font();AssetDatabase.CreateAsset(font, _fontsDir);}_setFontInfo(AssetDatabase.LoadAssetAtPath<Font>(_fontsDir),AssetDatabase.GetAssetPath(_fontTextAsset),_fontTexture);font = AssetDatabase.LoadAssetAtPath<Font>(_fontsDir);font.material = mat;}else{Debug.LogError("創建失敗,請檢查配置");}}EditorGUILayout.EndVertical();}private void _setFontInfo(Font font, string fontConfig, Texture texture){XmlDocument xml = new XmlDocument();xml.Load(fontConfig);List<CharacterInfo> chtInfoList = new List<CharacterInfo>();XmlNode node = xml.SelectSingleNode("font/chars");foreach (XmlNode nd in node.ChildNodes){XmlElement xe = (XmlElement)nd;int x = int.Parse(xe.GetAttribute("x"));int y = int.Parse(xe.GetAttribute("y"));int width = int.Parse(xe.GetAttribute("width"));int height = int.Parse(xe.GetAttribute("height"));int advance = int.Parse(xe.GetAttribute("xadvance"));CharacterInfo info = new CharacterInfo();info.glyphHeight = texture.height;info.glyphWidth = texture.width;info.index = int.Parse(xe.GetAttribute("id"));//這里注意下UV坐標系和從BMFont里得到的信息的坐標系是不一樣的哦,前者左下角為(0,0),//右上角為(1,1)。而后者則是左上角上角為(0,0),右下角為(圖寬,圖高)info.uvTopLeft = new Vector2((float)x / texture.width, 1 - (float)y / texture.height);info.uvTopRight = new Vector2((float)(x + width) / texture.width, 1 - (float)y / texture.height);info.uvBottomLeft = new Vector2((float)x / texture.width, 1 - (float)(y + height) / texture.height);info.uvBottomRight = new Vector2((float)(x + width) / texture.width, 1 - (float)(y + height) / texture.height);info.minX = 0;info.minY = -height;info.maxX = width;info.maxY = 0;info.advance = advance;chtInfoList.Add(info);}font.characterInfo = chtInfoList.ToArray();AssetDatabase.Refresh();} }在FontTools目錄下打開BMFont彈窗,選擇上面制作好的Font文件,點擊"Generate Font"按鈕,即可生成:
如果沒有異常的話會生成如下兩個文件:
點擊Font文件,可看到如下信息,"Line Spacing"一般設置為1,第一個項目是標點,因為圖片的高度只有100,而其它圖片高度有244,所以這里設置Y偏移-144,這樣才能顯示正確,如果圖片高度都是一樣的話就不用設置了。
四、使用字體
新建Text文本,把文本的字體設置成上面制作的字體就可以了。
?
另外附上了段切割圖片的代碼(如果數字切在一張圖片里,可以使用這個把數字切成單張素材再制作字體)
public static class ImageSlicer {[MenuItem("Assets/切割圖片/Process to Sprites")]static void ProcessToSprite(){Texture2D image = Selection.activeObject as Texture2D;//獲取旋轉的對象string rootPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(image));//獲取路徑名稱string path = rootPath + "/" + image.name + ".PNG";//圖片路徑名稱TextureImporter texImp = AssetImporter.GetAtPath(path) as TextureImporter;//獲取圖片入口AssetDatabase.CreateFolder(rootPath, image.name);//創建文件夾foreach (SpriteMetaData metaData in texImp.spritesheet)//遍歷小圖集{Texture2D myimage = new Texture2D((int)metaData.rect.width, (int)metaData.rect.height);for (int y = (int)metaData.rect.y; y < metaData.rect.y + metaData.rect.height; y++)//Y軸像素{for (int x = (int)metaData.rect.x; x < metaData.rect.x + metaData.rect.width; x++)myimage.SetPixel(x - (int)metaData.rect.x, y - (int)metaData.rect.y, image.GetPixel(x, y));}//轉換紋理到EncodeToPNG兼容格式if (myimage.format != TextureFormat.ARGB32 && myimage.format != TextureFormat.RGB24){Texture2D newTexture = new Texture2D(myimage.width, myimage.height);newTexture.SetPixels(myimage.GetPixels(0), 0);myimage = newTexture;}var pngData = myimage.EncodeToPNG();File.WriteAllBytes(rootPath + "/" + image.name + "/" + metaData.name + ".PNG", pngData);// 刷新資源窗口界面AssetDatabase.Refresh();}} }?
總結
以上是生活随笔為你收集整理的Unity BMFont自定义字体的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BMFont制作美术字体包教包会
- 下一篇: BMFont艺术字库制作