在Unity中,制作自定义字体
参考Unity UGUI 数字使用图片显示-BMFont
Unity / custom font自定义字体
说明
游戏中的数字(尤其是头顶飘血等),有时需要使用比较个性化的风格。
可以使用图片(其中包含对应的字)生成字体。
步骤
1 制作图片
图片中包含所有想要的字。
每个字占用的区域范围最好是相同的,以方便在Unity中切割成小图。
image.png
2 将图片按字切分成若干小图
在Unity中
通过SpriteEditor将原图拆成小图
image.png
选中原图,Tools->SplitTexture
image.png
可在与原图同目录下生成同名目录,在其中将前述小图分别生成独立的png。
image.png
3 借助bmfont,将前面做好的小图转成fnt和png
bmfont下载地址
打开bmfont64.exe,获知 0~9 的Id是 48~57。
Edit->Open Image Manager,在打开的Image Manager中点击Image -> Import Image...
导入图片“0”,将Id填为48.
image.png
关闭Bitmap font generator,可看到在bmfont64.exe同目录下生成文件bmfont.bmfc。
image.png
用文本编辑器打开这个文件,在它的底端可看到前面载入的图片信息,将其余图片的信息填入,保存。
image.png
image.png
再次打开bmfont64.exe,打开Image Manager确认通过前述直接修改文件的方式成功载入了其他图片。
image.png
Options -> Export options,按下图进行设置。
image.png
Options -> Save bitmap font as : 生成一个fnt文件和一个png文件。
image.png
4 在Unity中,将fnt和png转成字体
将前一步得到的fnt和png放入Unity工程中。
Unity菜单栏:BitmapFontExporter->Create:将这2个文件拖入工具,生成字体。
image.png
可以微调各字符的Advance(字符宽度)来控制相邻两字符的间距。
image.png
5 在Unity中做好的字体的显示效果
image.png
工具
image.png
BitmapFontExporter
用法:BitmapFontExporter->Create,将通过bmfont生成的fnt和png拖入,点击Create,生成fontsettings和mat。
using UnityEngine;using UnityEditor;using System.IO;using System.Xml;using System;public class BitmapFontExporter : ScriptableWizard{ private static void CreateFont() { ScriptableWizard.DisplayWizard<BitmapFontExporter>("Create Font"); } public TextAsset fontFile; public Texture2D textureFile; private void OnWizardCreate() { if (fontFile == null || textureFile == null) { return; } string path = EditorUtility.SaveFilePanelInProject("Save Font", fontFile.name, "", ""); if (!string.IsNullOrEmpty(path)) { ResolveFont(path); } } private void ResolveFont(string exportPath) { if (!fontFile) throw new UnityException(fontFile.name + "is not a valid font-xml file"); Font font = new Font(); XmlDocument xml = new XmlDocument(); xml.LoadXml(fontFile.text); XmlNode info = xml.GetElementsByTagName("info"); XmlNodeList chars = xml.GetElementsByTagName("chars").ChildNodes; CharacterInfo[] charInfos = new CharacterInfo; for (int cnt = 0; cnt < chars.Count; cnt++) { XmlNode node = chars; CharacterInfo charInfo = new CharacterInfo(); charInfo.index = ToInt(node, "id"); charInfo.width = ToInt(node, "xadvance"); charInfo.uv = GetUV(node); charInfo.vert = GetVert(node); charInfos = charInfo; } Shader shader = Shader.Find("Unlit/Transparent"); Material material = new Material(shader); material.mainTexture = textureFile; AssetDatabase.CreateAsset(material, exportPath + ".mat"); font.material = material; font.name = info.Attributes.GetNamedItem("face").InnerText; font.characterInfo = charInfos; AssetDatabase.CreateAsset(font, exportPath + ".fontsettings"); } private Rect GetUV(XmlNode node) { Rect uv = new Rect(); uv.x = ToFloat(node, "x") / textureFile.width; uv.y = ToFloat(node, "y") / textureFile.height; uv.width = ToFloat(node, "width") / textureFile.width; uv.height = ToFloat(node, "height") / textureFile.height; uv.y = 1f - uv.y - uv.height; return uv; } private Rect GetVert(XmlNode node) { Rect uv = new Rect(); uv.x = ToFloat(node, "xoffset"); uv.y = ToFloat(node, "yoffset"); uv.width = ToFloat(node, "width"); uv.height = ToFloat(node, "height"); uv.y = -uv.y; uv.height = -uv.height; return uv; } private int ToInt(XmlNode node, string name) { return Convert.ToInt32(node.Attributes.GetNamedItem(name).InnerText); } private float ToFloat(XmlNode node, string name) { return (float)ToInt(node, name); }}SplitTexture
用法:在Project中选定一张图,Tools->SplitTexture
// SplitTexture.csusing UnityEngine;using UnityEditor;using System.IO;/// <summary>/// 将图片分离成多张小图/// </summary>public class SplitTexture{ static void DoSplitTexture() { // 获取所选图片 Texture2D selectedImg = Selection.activeObject as Texture2D; string rootPath = Path.GetDirectoryName(AssetDatabase.GetAssetPath(selectedImg)); string path = rootPath + "/" + selectedImg.name + ".png"; TextureImporter texImp = AssetImporter.GetAtPath(path) as TextureImporter; // 设置为可读 texImp.isReadable = true; AssetDatabase.ImportAsset(path); // 创建文件夹 AssetDatabase.CreateFolder(rootPath, selectedImg.name); foreach (SpriteMetaData metaData in texImp.spritesheet) { var width = (int)metaData.rect.width; var height = (int)metaData.rect.height; Texture2D smallImg = new Texture2D(width, height); var pixelStartX = (int)metaData.rect.x; var pixelEndX = pixelStartX + width; var pixelStartY = (int)metaData.rect.y; var pixelEndY = pixelStartY + height; for (int x = pixelStartX; x <= pixelEndX; ++x) { for (int y = pixelStartY; y <= pixelEndY; ++y) { smallImg.SetPixel(x - pixelStartX, y - pixelStartY, selectedImg.GetPixel(x, y)); } } //转换纹理到EncodeToPNG兼容格式 if (TextureFormat.ARGB32 != smallImg.format&& TextureFormat.RGB24 != smallImg.format) { Texture2D img = new Texture2D(smallImg.width, smallImg.height); img.SetPixels(smallImg.GetPixels(0), 0); smallImg = img; } // 保存小图文件 string smallImgPath = rootPath + "/" + selectedImg.name + "/" + metaData.name + ".png"; File.WriteAllBytes(smallImgPath, smallImg.EncodeToPNG()); // 刷新资源窗口界面 AssetDatabase.Refresh(); // 设置小图的格式 TextureImporter smallTextureImp = AssetImporter.GetAtPath(smallImgPath) as TextureImporter; // 设置为可读 smallTextureImp.isReadable = true; // 设置alpha通道 smallTextureImp.alphaIsTransparency = true; // 不开启mipmap smallTextureImp.mipmapEnabled = false; AssetDatabase.ImportAsset(smallImgPath); } }}
页:
[1]