系统字体,不占空间,效果一般。

自己拖的.TTF文件形成的字体,占空间很大,有特殊效果。一个TTF字库差不多占用3M左右,之所以这么大,是因为里面包含了所有的字,就像一本字典一样,所以字符都在里面。

但是我们开发游戏,并不需要用到所有的字,有的时候可能就只用到其中的几十个字,所以可以用一种解决方案,使得文字的效果好,同时占很小的空间。

这种方案就是Bmpfont,前提是有限的字符和好的字体。

用工具GlyphDesigner (Mac系统),把有限的字符添加字体效果后,绘制在一张png大图上,同时附加一个.fnt的配置文件,里面记录了文字在图片中的位置坐标信息,用于匹配,如Advance表示的是下一个字符开始的位置

就是说有了这个fnt文件,系统才能找到这个字在图片中的哪个位置,从而复制出来显示。

一、Bmpfont

1.把fnt文件和png文件拖进Resources文件夹下面

2.创建一个Canvas

3.对Canvas进行初始化,记得把Game视图的分辨率调成和Canvas里面设置的一样的分辨率640X960

4.创建一个Image的UI节点作为Canvas的子节点,名字叫bg,拖进背景图片到这个节点中。

5.创建一个Text类型的UI节点叫text

6.创建一个类似TTF类型的字库资源文件在Resources文件下create--->custom font,名字改成和fnt文件一样

7.创建一个材质球create--->material,名字改成和fnt文件一样,Shader属性改成GUI/Text Shader(用默认颜色覆盖原来颜色)或者Moboile/Diffuse(原样),把png图片设置为Sprite后拖进材质球的贴图属性。

8.把类似TTF类型的字库资源文件的Default Material属性拖进第7步的材质球,再手动计算和输入每一个字符的参数属性,size=1表示只有一个字符,其他的参数在fnt文件里面找。

计算公式:

char id=52 x=2 y=2 width=25 height=33 xoffset=0 yoffset=0 xadvance=20 page=0 chnl=0 letter="4"
UV
X = x / 贴图宽(2/128 = 0.015625) ; Y = 1 - y / 贴图高(1- 2/128 = 0.984375)
W = width / 贴图宽(25/128 = 0.1953125) ; H = -1 * height / 贴图高 (-33/128 = -0.2578125)
Vert
X = xoffset (0) ; Y = yoffset (-0.5 * height)
W = width(25) ; H = height(33) advance = xadvance (20);

9.把类似TTF类型的字库资源文件拖进text的UI节点的Character--->font字体属性中。

10.text节点中的text属性里面输入想显示的字符,必须是在png图片中有的且被我们手动录入的字符。

二、扩展编辑器

上面第七步需要手动一个一个计算字符参数和添加字符进去,非常麻烦,有一种方案可以便捷一点,就是扩展编辑器

1.在Assets文件夹下面创建一个叫做Editor的文件夹,必须叫这个,不然等下里面放的脚本会和平时写的脚本混在一起。

2.把字符处理脚本(网上下载的),放进Editor文件夹下

3.字符处理脚本CreateFontEditor:

using UnityEngine;
using UnityEditor;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions; // 创建bmfont
// 继承自编辑器的扩展,用来扩展我们的编辑器的,应该放到Editor这个目录下; public class CreateFontEditor : Editor
{
// 制定我们入口的菜单
[MenuItem("Assets/Create/CreateBMFont")]
static void CreateFont()
{
// 当前选择的物体
Object obj = Selection.activeObject;
// Unity API 返回当前你选择的资源的路径
string fntPath = AssetDatabase.GetAssetPath(obj);
Debug.Log("#####" + fntPath); // 程序需要从fnt文件里面导入我们字模信息;
if (fntPath.IndexOf(".fnt") == -)
{
// 不是字体文件
return;
} // your_name.fnt --> your_name.fontsetting;名字一致
// new path --> .fnt --> .fontsettings;
string customFontPath = fntPath.Replace(".fnt", ".fontsettings");
if (!File.Exists(customFontPath))
{
return;
} Debug.Log(fntPath);
StreamReader reader = new StreamReader(new FileStream(fntPath, FileMode.Open)); List<CharacterInfo> charList = new List<CharacterInfo>(); Regex reg = new Regex(@"char id=(?<id>\d+)\s+x=(?<x>\d+)\s+y=(?<y>\d+)\s+width=(?<width>\d+)\s+height=(?<height>\d+)\s+xoffset=(?<xoffset>\d+)\s+yoffset=(?<yoffset>\d+)\s+xadvance=(?<xadvance>\d+)\s+");
string line = reader.ReadLine();
int lineHeight = ;
int texWidth = ;
int texHeight = ; while (line != null)
{
if (line.IndexOf("char id=") != -)
{
Match match = reg.Match(line);
if (match != Match.Empty)
{
var id = System.Convert.ToInt32(match.Groups["id"].Value);
var x = System.Convert.ToInt32(match.Groups["x"].Value);
var y = System.Convert.ToInt32(match.Groups["y"].Value);
var width = System.Convert.ToInt32(match.Groups["width"].Value);
var height = System.Convert.ToInt32(match.Groups["height"].Value);
var xoffset = System.Convert.ToInt32(match.Groups["xoffset"].Value);
var yoffset = System.Convert.ToInt32(match.Groups["yoffset"].Value);
var xadvance = System.Convert.ToInt32(match.Groups["xadvance"].Value); CharacterInfo info = new CharacterInfo();
info.index = id;
float uvx = 1f * x / texWidth;
float uvy = - (1f * y / texHeight);
float uvw = 1f * width / texWidth;
float uvh = -1f * height / texHeight; info.uvBottomLeft = new Vector2(uvx, uvy);
info.uvBottomRight = new Vector2(uvx + uvw, uvy);
info.uvTopLeft = new Vector2(uvx, uvy + uvh);
info.uvTopRight = new Vector2(uvx + uvw, uvy + uvh); info.minX = xoffset;
info.minY = yoffset + height / ; // 这样调出来的效果是ok的,原理未知
info.glyphWidth = width;
info.glyphHeight = -height; // 同上,不知道为什么要用负的,可能跟unity纹理uv有关
info.advance = xadvance; charList.Add(info);
}
}
else if (line.IndexOf("scaleW=") != -)
{
Regex reg2 = new Regex(@"common lineHeight=(?<lineHeight>\d+)\s+.*scaleW=(?<scaleW>\d+)\s+scaleH=(?<scaleH>\d+)");
Match match = reg2.Match(line);
if (match != Match.Empty)
{
lineHeight = System.Convert.ToInt32(match.Groups["lineHeight"].Value);
texWidth = System.Convert.ToInt32(match.Groups["scaleW"].Value);
texHeight = System.Convert.ToInt32(match.Groups["scaleH"].Value);
}
}
line = reader.ReadLine();
} Font customFont = AssetDatabase.LoadAssetAtPath<Font>(customFontPath);
customFont.characterInfo = charList.ToArray();
AssetDatabase.SaveAssets();
AssetDatabase.Refresh();
Debug.Log(customFont);
}
}

4.添加好custom font资源文件的文字材质球后,对想要手动添加字符的custom font资源文件使用右键--->Create--->CreateBMFont就可以把fnt文件里面的每一个字符和它的参数都计算添加到custom font资源文件里面

5.把custom font资源文件拖进text的UI节点的font属性,就可以使用了。

关于Unity中的Bmpfont的使用的更多相关文章

  1. Unity中使用Attribute

    Attribute是c#的语言特性 msdn说明如下: The Attribute class associates predefined system information or user-def ...

  2. 在Unity中使用UGUI修改Mesh绘制几何图形

    在商店看到这样一个例子,表示很有兴趣,他们说是用UGUI做的.我想,像这种可以随便变形的图形,我第一个就想到了网格变形. 做法1: 细心的朋友应该会发现,每个UGUI可见元素,都有一个‘Canvas ...

  3. Unity中使用WebView

    Unity中使用WebView @(设计) 需求,最近游戏中需要引入H5直播页面和更新比较频繁的赛事页面,需求包括:加密传参数.和Unity交互,在Unity框架下其实有几种方案: 内置函数Appli ...

  4. Unity中创建二维码

    在网络上发现了一个可以把字符串转换成二维码的dll,但是我们要怎么使用他呢.不废话,直接进入主题. 用到的引用 using UnityEngine;using ZXing;using ZXing.Qr ...

  5. 在Unity中创建可远程加载的.unity3d包

    在一个Unity项目中,发布包本身不一定要包括所有的Asset(译为资产或组件),其它的部分可以单独发布为.unity3d,再由程序从本地/远程加载执行,这部分不在本文讨论范围.虽然Unity并没有直 ...

  6. 【原创翻译】初识Unity中的Compute Shader

    一直以来都想试着自己翻译一些东西,现在发现翻译真的很不容易,如果你直接把作者的原文按照英文的思维翻译过来,你会发现中国人读起来很是别扭,但是如果你想完全利用中国人的语言方式来翻译,又怕自己理解的不到位 ...

  7. 【unity shaders】:Unity中的Shader及其基本框架

    shader和Material的基本关系 Shader(着色器)实际上就是一小段程序,它负责将输入的Mesh(网格)以指定的方式和输入的贴图或者颜色等组合作用,然后输出.绘图单元可以依据这个输出来将图 ...

  8. Unity中各个平台的预编译的运用方式

    1,unity中官方文档的一个操纵关键词   Platform Dependent Compilation 2,常用的预编译关键词    UNITY_EDITOR    编辑器调用.UNITY_STA ...

  9. 解读Unity中的CG编写Shader系列七(不透明度与混合)

    转自http://www.itnose.net/detail/6098539.html 1.不透明度 当我们要将两个半透的纹理贴图到一个材质球上的时候就遇到混合的问题,由于前面的知识我们已经知道了片段 ...

随机推荐

  1. PLSQL_统计信息系列03_统计信息的收集

    20150506 Created By Baoxinjian

  2. System V 共享内存 和 系列函数

    跟消息队列一样,共享内存也有自己的数据结构,如下: struct shmid_ds { struct ipc_perm shm_perm;    /* Ownership and permission ...

  3. 【服务器防护】linux 如何查看防火墙是否开启

    service iptables status可以查看到iptables服务的当前状态.但是即使服务运行了,防火墙也不一定起作用,你还得看防火墙规则的设置 iptables -L在此说一下关于启动和关 ...

  4. 面向对象中private理解

    我们大家都知道思想訪问修饰符.public,protected,private,那么我们知道了继承中private私有属性能够继承吗?我么接下来做个小实验 class A {     private ...

  5. vim:去掉响铃

    vim在移动字符出界(上下左右)包括按<ESC>建都会响铃,有时候真的很烦. 在网上搜了一下,原来是visualbell来控制的,在vim里使用命令:help visualbell,原来禁 ...

  6. JS动态创建Table,Tr,Td并赋值

    JS动态创建Table,Tr,Td并赋值. 成果库修改: 要求主题列表随成果类型改变而改变 网上查询资料后开工,在成果类型下拉框添加change()事件触发Dwr,查询主题集合——动态创建/编辑Tab ...

  7. 网站的PV UV IP---网站常见软件性能

    IP,衡量不同时间段的上网人数.00:00-24:00内相同的地址被计算一次.例:日300W IP,至少300W人访问PV,衡量页面受欢迎程度.每刷新一次,被记录一次(刷pv),网站被访问的页面的数量 ...

  8. [na][dhcp]华为DHCP-重要

    近日遇到遇到控制器和wac对接的一些问题.尤其是地址池这块排查起来比较费事,且这些命令不容易找到,以下是能经常用到的命令. 1,查看ip是否冲突: (看下conflict字段) 2,防止冲突命令: 3 ...

  9. 【Android】18.1 利用安卓内置的定位服务实现位置跟踪

    分类:C#.Android.VS2015: 创建日期:2016-03-04 一.安卓内置的定位服务简介 通常将各种不同的定位技术称为位置服务或定位服务.这种服务是通过电信运营商的无线电通信网络(如GS ...

  10. Java并发:volatile内存可见性和指令重排

    volatile两大作用 1.保证内存可见性 2.防止指令重排 此外需注意volatile并不保证操作的原子性. (一)内存可见性 1 概念 JVM内存模型:主内存和线程独立的工作内存 Java内存模 ...