首页 文章详情

unity使用BMFont制作位图字体

爱上游戏开发 | 473 2021-12-27 19:05 0 0 0
UniSMS (合一短信)

介绍

在游戏中制作中,我们往往会遇到自定义字体的情况,但是unity自带的字体Arial,无法满足我们对字体的需求。虽然我们可以导入字体,但是并不一定符合我们的需要,这个时候就需要使用自定义字体来显示某些东西以达到某种视觉效果,例如:

BmFont准备

下载:http://www.angelcode.com/products/bmfont/

认识bmFont

首先,双击安装好的软件软件打开,初始界面如下:是不是看上去密密麻麻,手足无措,不要担心,很简单的,我们一步一步来。

上方选择区域

在这里插入图片描述

可以看到的是上方选择区域只有两个,Options和Edit。

  • Options主要是对整张位图字体的操作
  • Edit是对里面单个或多个字符的操作。用个形象的比喻:一张纸代表Options,纸张的大小等设置是Options管理;而里面的每一个字符,则有Edit决定。这样比喻形象多了吧~

中间区域

中间区域几乎包含了所有常见的字符右边区域可以暂时不用管,目前也没用到过,目测应该是语言字体之类的。

右下方

就制作位图字体而言,右下方提供给我们一个字符对应的id(即ASCII码)

制作位图字体

首先,我们来制作一个字符:Edit–>OpenImgageManager,打开ImageManager界面

Image->importImage,选择图片选择要导入的一张字符图片后会出现如下弹窗:注意Id,id对应字符的ASCII码。

那么,如何知道某个字符的id或者ASCII码呢,接下来就回到上文了,还记得上文介绍BmFont界面时的介绍的右下方吗,第一个值(48)就是我们需要填写的id值。

那么这时候问题又来了,如何查看每个字符的id值呢?不要担心,其实很简单,只需要把鼠标移动到中间区域对应的字符上,即可在右下方查看,如图所示:

导入成功后,我们会在ImageManager界面看到字符信息:左边代表id,右边是对应的美术资源路径。回到BM Font主界面,可以看,对应字符右下角有一个小标志,该标志代表制作成功的字符。当我们把需要制作的位图字体导入成功后,接下来就是设置位图了。选择Options->Export options打开导出选项界面。微信搜索公众号 [爱上游戏开发],回复 “资料”,免费领取 200G 学习资料!

  1. 设置整张位图的长款。
  2. 设置字体的导出格式。
  3. 确认设置。

接下来就是保存位图了,选择Options-> Save bitmap font as选择你要保存的路径,并修改命名,这里我改为test并保存。保存成功后会得到两个文件,分别是.png和.fnt至此,位图字体就已经制作完成了,接下来了解在Unity中使用该字体吧!

Unity使用位图字体

新建Font文件夹,并将上面制作好的位图字体拖·进去。新建一个Materia设置如下:shader–>TextShader并设置FontTexture的值如下(即上文提到的.png文件):

新建CustomFont,将上文创建的材质球拖到如图所示位置,设置如下:下面,用个动图介绍一下位图字体在unity中的使用准备:正当你以为结束的时候,你会发现新建Text,使用新字体,没有任何显示,这时候你查看会发现test.mat里面是空的。这时候不要急,下面我们就来为test.mat赋值,新建C#脚本CustomFontImportor,添加如下代码:

using UnityEngine;
using System.Collections;
using System.Xml;
using System;


public class CustomFontImportor : MonoBehaviour
{
    public Font font;
    public TextAsset textAsset;


    void Awake()
    
{
        if (font == null || textAsset == null)
        {
            //Debug.LogError("请设置font和textAsset.");
            return;
        }

        XmlDocument xmlDocument = new XmlDocument();
        xmlDocument.LoadXml(textAsset.text);


        int totalWidth = Convert.ToInt32(xmlDocument["font"]["common"].Attributes["scaleW"].InnerText);
        int totalHeight = Convert.ToInt32(xmlDocument["font"]["common"].Attributes["scaleH"].InnerText);

        XmlElement xml = xmlDocument["font"]["chars"];
        ArrayList characterInfoList = new ArrayList();


        for (int i = 0; i < xml.ChildNodes.Count; ++i)
        {
            XmlNode node = xml.ChildNodes[i];
            if (node.Attributes == null)
            {
                continue;
            }
            int index = Convert.ToInt32(node.Attributes["id"].InnerText);
            int x = Convert.ToInt32(node.Attributes["x"].InnerText);
            int y = Convert.ToInt32(node.Attributes["y"].InnerText);
            int width = Convert.ToInt32(node.Attributes["width"].InnerText);
            int height = Convert.ToInt32(node.Attributes["height"].InnerText);
            int xOffset = Convert.ToInt32(node.Attributes["xoffset"].InnerText);
            int yOffset = Convert.ToInt32(node.Attributes["yoffset"].InnerText);
            int xAdvance = Convert.ToInt32(node.Attributes["xadvance"].InnerText);
            CharacterInfo info = new CharacterInfo();
            Rect uv = new Rect();
            uv.x = (float)x / totalWidth;
            uv.y = (float)(totalHeight - y - height) / totalHeight;
            uv.width = (float)width / totalWidth;
            uv.height = (float)height / totalHeight;
            info.index = index;
            info.uvBottomLeft = new Vector2(uv.xMin, uv.yMin);
            info.uvBottomRight = new Vector2(uv.xMax, uv.yMin);
            info.uvTopLeft = new Vector2(uv.xMin, uv.yMax);
            info.uvTopRight = new Vector2(uv.xMax, uv.yMax);
            info.minX = xOffset;
            info.maxX = xOffset + width;
            info.minY = -yOffset - height;
            info.maxY = -yOffset;
            info.advance = xAdvance;
            info.glyphWidth = width;
            info.glyphHeight = height;
            characterInfoList.Add(info);
        }
        font.characterInfo = characterInfoList.ToArray(typeof(CharacterInfo)) as CharacterInfo[];
        Debug.Log("生成成功.");
    }
}

将CustomFontImportor脚本拖到场景中的物体身上,并运行场景,我们会可看到有一个“生成成功”的日志输出,这是选中test.mat查看发现,已经被成功赋值了。接下来你就可以Unity中肆无忌惮的使用新制作的位图字体拉~

-- END --


公众号后台回复「资料」获取超多学习福利

>>> 点击进入技术讨论群 <<<
▽想深入了解么?

长按/扫码关注我吧↑↑↑

觉得不错就点个在看

good-icon 0
favorite-icon 0
收藏
回复数量: 0
    暂无评论~~
    Ctrl+Enter