RedZero9 发表于 2022-4-28 14:32

在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]
查看完整版本: 在Unity中,制作自定义字体