Unity UGUI 数字使用图片显示

Wesley13
• 阅读 763

Unity UGUI 数字使用图片显示-BMFont

BMFont

之前使用Cocos引擎的时候需要用到艺术字也就是将数字使用美术给的图片来代替显示,也就是要做一个新字体专门用来显示艺术字,当时用的是BMFont来制作字体。那么问题来了,在Unity下面的UGUI能否使用呢?答案当然是OK的啦。

下面我们来看下如何使用BMFont。

从网站https://www.angelcode.com/products/bmfont/下载并安装BMFont软件。

制作

我们通过菜单栏“Edit/Open Image Manager”来选择需要做艺术字的图片。

Unity UGUI 数字使用图片显示

打开之后选择”Image/Import image“

Unity UGUI 数字使用图片显示

点击”Browse“按钮选择数字0的png图片,然后在Id一栏填写该数字的Id也就是如下的箭头所示的48,即数字0的ASCII码。

Unity UGUI 数字使用图片显示

Unity UGUI 数字使用图片显示

点击OK就会将图片给导入进来。

导入的图片不显示

但是需要注意这个时候可能会出现点击之后Image Manager面板里面并没有出现刚才加载的图片。这里是美术给的图片格式不对,我们需要将png图片修改为PNG-24格式的。打开PS加载出对应点png图片,然后菜单栏选择“文件/存储为Web所用格式”。

Unity UGUI 数字使用图片显示

在弹出的面板图中所示的位置选择PNG-24格式,点击存储即可。

Unity UGUI 数字使用图片显示

我们依次添加完所有的数字png图片之后,在BMFont的菜单栏“Options/Export options”里面设置一下导出的参数。

Unity UGUI 数字使用图片显示

图片的Width和Height可以自己根据里面的图片大小自己设置(设置好之后可以不必着急关闭窗口,在导出时候查看生产的所有的数字合并之后的图片大小是否合适,里面的数字排版是否紧凑。一开始设置大了或者小了,后面还可以修改大小,重新导出)。

Unity UGUI 数字使用图片显示

下面的Font description 更改为XML,后面需要根据这个格式生成对应的字体文件。然后Texture格式设置为png。点击Ok即可。接下来就是回到BMFont的菜单栏选择“Options/Save bitmap font as...”即可保存出Score.fnt文件,同时生成的还有一个对应的png大图。

Unity UGUI 数字使用图片显示

我们将生成的Score.fnt和Score_0.png一起放入Unity中,然后新建一个BitmapFontExporter.cs文件放入Unity的Editor目录,代码如下:

using UnityEngine;using UnityEditor;using System.IO;using System.Xml;using System;public class BitmapFontExporter : ScriptableWizard{    [MenuItem("BitmapFontExporter/Create")]    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")[0];        XmlNodeList chars = xml.GetElementsByTagName("chars")[0].ChildNodes;        CharacterInfo[] charInfos = new CharacterInfo[chars.Count];        for (int cnt = 0; cnt < chars.Count; cnt++)        {            XmlNode node = chars[cnt];            CharacterInfo charInfo = new CharacterInfo();            charInfo.index = ToInt(node, "id");            charInfo.width = ToInt(node, "xadvance");            charInfo.uv = GetUV(node);            charInfo.vert = GetVert(node);            charInfos[cnt] = 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);    }}

然后我们在Unity的菜单栏选择“BitmapFontExporter/Creat”即可打开字体创建面板。

Unity UGUI 数字使用图片显示

在打开的面板中将生成的XML文件和png大图拖拽进去,点击Create按钮即可生成Score字体。

Unity UGUI 数字使用图片显示

在Unity中可以看到这张png大图里面的所有数字的排列紧凑程度,也就是上面提到的。

Unity UGUI 数字使用图片显示

原理


Unity提供了一个自定义字体的方法,在Unity中右键“Create/Custom Font“会生成一个自定义的字体,不过需要我们手动去填写字体对应的材质球和Character Rects。size大小表示有多少个艺术字,然后要在每个Element里面的index填写字符对应的ASCII码,还要填写对应的UV和Vert。

Unity UGUI 数字使用图片显示

不过这个过程相当繁琐,所以通过代码来完成这一步骤。原理很简单,就是将BMFont生成出来的XML配置文件读取出来,依次填写进去即可。

Unity UGUI 数字使用图片显示

Unity UGUI 数字使用图片显示

使用

在UGUI的Text组件里面选择刚才生成的字体拖拽进去即可,具体如下

Unity UGUI 数字使用图片显示

Unity UGUI 数字使用图片显示

参考:https://tedsieblog.wordpress.com/category/unity-ugui/

本文分享自微信公众号 - Unity游戏开发笔记(UnityGameDeveloper)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
2年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
皕杰报表(关于日期时间时分秒显示不出来)
在使用皕杰报表设计器时,数据据里面是日期型,但当你web预览时候,发现有日期时间类型的数据时分秒显示不出来,只有年月日能显示出来,时分秒显示为0:00:00。1.可以使用tochar解决,数据集用selecttochar(flowdate,"yyyyMMddHH:mm:ss")fromtablename2.也可以把数据库日期类型date改成timestamp
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
3个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这