使用BMFont的方式,目的是得到fnt文件,实际上是xml格式文件。
<font>
<info face="font" size="80" />
<common lineHeight="80" scaleW="122" scaleH="114" pages="1" />
<pages>
<page id="0" file="font.png" />
</pages>
<chars count="13">
<char id="48" x="32" y="0" width="31" height="37" xoffset="0" yoffset="43" xadvance="32" /><!-- 0 -->
<char id="49" x="64" y="76" width="28" height="37" xoffset="0" yoffset="43" xadvance="29" /><!-- 1 -->
<char id="50" x="32" y="76" width="31" height="37" xoffset="0" yoffset="43" xadvance="32" /><!-- 2 -->
<char id="51" x="64" y="38" width="30" height="37" xoffset="0" yoffset="43" xadvance="31" /><!-- 3 -->
<char id="52" x="64" y="0" width="31" height="37" xoffset="0" yoffset="43" xadvance="32" /><!-- 4 -->
<char id="53" x="0" y="0" width="31" height="37" xoffset="0" yoffset="43" xadvance="32" /><!-- 5 -->
<char id="54" x="32" y="38" width="31" height="37" xoffset="0" yoffset="43" xadvance="32" /><!-- 6 -->
<char id="55" x="93" y="76" width="28" height="37" xoffset="0" yoffset="43" xadvance="29" /><!-- 7 -->
<char id="56" x="0" y="76" width="31" height="37" xoffset="0" yoffset="43" xadvance="32" /><!-- 8 -->
<char id="57" x="0" y="38" width="31" height="37" xoffset="0" yoffset="43" xadvance="32" /><!-- 9 -->
<char id="58" x="95" y="38" width="20" height="30" xoffset="0" yoffset="50" xadvance="21" /><!-- : -->
<char id="32" x="0" y="0" width="0" height="0" xoffset="0" yoffset="0" xadvance="20" /><!-- -->
<char id="9" x="0" y="0" width="0" height="0" xoffset="0" yoffset="0" xadvance="160" /><!-- -->
</chars>
<kernings count="0">
</kernings>
</font>
得到图集个fnt文件后,网上一般的方法是手动计算在Unity中的参数,有些繁琐,在这里写一个Editor脚本来自动完成这个过程。直接上代码:
using System;
using System.Collections.Generic;
using System.IO;
using System.Xml;
using UnityEditor;
using UnityEngine;
public class CreateFontFromFnt : EditorWindow
{
[MenuItem("Tools/创建字体(Fnt)")]
static void DoIt()
{
GetWindow<CreateFontFromFnt>("创建字体");
}
private string fontName;
private string fontPath;
private Texture2D tex;
private string fntFilePath;
private void OnGUI()
{
GUILayout.BeginVertical();
GUILayout.BeginHorizontal();
GUILayout.Label("字体名称:");
fontName = EditorGUILayout.TextField(fontName);
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
GUILayout.Label("字体图片:");
tex = (Texture2D)EditorGUILayout.ObjectField(tex, typeof(Texture2D), true);
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
if (GUILayout.Button(string.IsNullOrEmpty(fontPath) ? "选择存储字体路径" : fontPath))
{
fontPath = EditorUtility.OpenFolderPanel("字体路径", Application.dataPath, "");
if (string.IsNullOrEmpty(fontPath))
{
Debug.Log("取消选择路径");
}
else
{
fontPath = fontPath.Replace(Application.dataPath, "") + "/";
}
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
if (GUILayout.Button(string.IsNullOrEmpty(fntFilePath) ? "选择fnt文件" : fntFilePath))
{
//桌面路径:Environment.GetFolderPath(Environment.SpecialFolder.Desktop
fntFilePath = EditorUtility.OpenFilePanelWithFilters("选择fnt文件", Application.dataPath, new string[] { "", "fnt" });
if (string.IsNullOrEmpty(fntFilePath))
{
Debug.Log("取消选择路径");
}
}
GUILayout.EndHorizontal();
GUILayout.BeginHorizontal();
if (GUILayout.Button("创建"))
{
Create();
}
GUILayout.EndHorizontal();
GUILayout.EndVertical();
}
private void Create()
{
if (string.IsNullOrEmpty(fntFilePath))
{
Debug.LogError("fnt为空");
return;
}
if (tex == null)
{
Debug.LogError("字体图片为空");
return;
}
string fontSettingPath = fontPath + fontName + ".fontsettings";
string matPath = fontPath + fontName + ".mat";
if (File.Exists(Application.dataPath + fontSettingPath))
{
Debug.LogErrorFormat("已存在同名字体文件:{0}", fontSettingPath);
return;
}
if (File.Exists(Application.dataPath + matPath))
{
Debug.LogErrorFormat("已存在同名字体材质:{0}", matPath);
return;
}
var list = new List<CharacterInfo>();
XmlDocument xmlDoc = new XmlDocument();
var content = File.ReadAllText(fntFilePath, System.Text.Encoding.UTF8);
xmlDoc.LoadXml(content);
var nodelist = xmlDoc.SelectNodes("font/chars/char");
foreach (XmlElement item in nodelist)
{
CharacterInfo info = new CharacterInfo();
var id = int.Parse(item.GetAttribute("id"));
var x = float.Parse(item.GetAttribute("x"));
var y = float.Parse(item.GetAttribute("y"));
var width = float.Parse(item.GetAttribute("width"));
var height = float.Parse(item.GetAttribute("height"));
info.index = id;
//纹理映射,上下翻转
info.uvBottomLeft = new Vector2(x / tex.width, 1 - (y + height) / tex.height);
info.uvBottomRight = new Vector2((x + width) / tex.width, 1 - (y + height) / tex.height);
info.uvTopLeft = new Vector2(x / tex.width, 1 - y / tex.height);
info.uvTopRight = new Vector2((x + width) / tex.width, 1 - y / tex.height);
info.minX = 0;
info.maxX = (int)width;
info.minY = -(int)height / 2;
info.maxY = (int)height / 2;
info.advance = (int)width;
list.Add(info);
}
Material mat = new Material(Shader.Find("GUI/Text Shader"));
mat.SetTexture("_MainTex", tex);
Font m_myFont = new Font();
m_myFont.material = mat;
AssetDatabase.CreateAsset(mat, "Assets" + matPath);
AssetDatabase.CreateAsset(m_myFont, "Assets" + fontSettingPath);
m_myFont.characterInfo = list.ToArray();
EditorUtility.SetDirty(m_myFont);
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log("创建成功!");
}
}