由于TextMeshPro的字体资源后缀是.asset,所以,需要我们借助插件的字体工具TextMeshPro-Font Asset Creator来生成新的字体资源。该工具打开路径:Window-Font Asset Creator。具体操作可见TextMeshPro/User Guide/TextMesh Pro User Guide.pdf这个文档,有详细介绍。
由于用到了中文字体,所以需要修改插件的源码。本篇博客还提供了常用的3500个字体的txt文档,下载链接:
制作字体的具体步骤如下:
1、生成txt字体文件
把你所需要的字体,粘贴复制到txt文档中,另存为,编码格式选择Unicode格式。关于字符编码格式,见上面的文章。点击打开链接 。
2、熟悉插件工具——Font Asset Creator
1)Font Source:设置字体格式,我用的是隶属,为了避免错误,尽量去Windows系统里拷贝字体过来即可。在工程目录下新建Fonts目录,拷贝进去。
2)Font Size:设置字体大小,最好是使用Auto Sizing
3)Font Padding:设置字体间距,像素为单位,512*512尺寸下,间距设置为5即可
4)Atlas Resolution:设置图集尺寸,根据字体多少来确定
5)Character Set:设置字体内容,即需要制作的字体资源包括哪些字体。(1)ASCII:仅包含ASCII的字符集;(2)ASCII Lowercase:小写ASCII字符集;(3)ASCIIUppercase:大写ASCII字符集;(4)Numbers+Symbols:数字+符号字符集;(5)Custom Range:可以定义一个范围的字符集,但是仅限于ASCII和拉丁字母,如在自定义窗口范围输入32-126或者161-255;(6)Custom Characters:自定义字符集,可以在自定义窗口输入自定义的字符;(7)Characters from File:从外部文件读入,即我们这片文章介绍的主要内容。当选择该模式时,可以拖拽一个txt文档到自定义窗口。如上图所示;
6)Font Style:字体格式设置,如加粗、下划线、outline等。但是这个设置是非必须的;
7)Font Render Mode:字体渲染模式。(1)Hinted Smooth:反锯齿渲染模式;(2)Smooth:和(1)差不多;(3)Raster Hinted:光栅渲染模式,带hinting效果;(4)Raster:光栅模式,不带hinting效果;(5)Signed Distance Field 16:创建SDF字体集的标准模式,字体采样使用16X,生成更精确的资源;(6)Signed Distance Field 32:使用32X采用,处理复杂的字体或者高频率曲线的变化,注意:这个处理方式显著低于16X的模式。
8)Get Kerning Pairs:暂时不懂,也没用到。
9)Generate Font Atlas:生成字体资源
10)Save TextMeshPro Font Asset:保存字体资源,是以.asset的后缀文件保存的。保存位置放在刚才创建的Fonts目录下即可,如果使用Signed Distance Field的渲染模式,将会生成在字体资源名称后加上SDF。
3、修改TextMeshPro源码
通过2生成的字体资源,我们在使用时会报The given key was not present in the dictionary:原因是这个插件是以ASCII为基础,处理的代码逻辑,所以需要做一些修改。通过代码我们可以看到,保存字体资源时,使用的是字典型的数据结构中,key值使用该字体当前编码方式下的10进制数。如“A"在ASCII编码格式下是65,保存时的key即为65。又如汉字”我“在Unicode编码格式下是\u6211,转换为十进制是25105,则保存时key值即为25105。而插件的源码中默认给我们添加了LineFeed(10)、Return(13)、Space(32)3个ASCII字符,所以这三个字符保存时使用的是ASCII下的编码值。因此,当我们使用Unicode时,如果插入ASCII的编码值,肯定会报错的。所以我们把它注释掉。即:TextMeshProFont.cs 151:添加 /* ; 202添加 /*; 208:65改为了12290;TMPro_Private.cs 453:Fonts/ARIAL SDF 改为UI/Fonts/SIMLI。可以自己全局搜索characterDictionary.TryGetValue,看看哪里使用到了自己没使用的key值,注释或者修改掉就可以了。保存,运行;
运行发现还是报错,再次检查发现,TextMeshPro默认给我们使用了Arial SDF,即TMPro_Private.cs 453行,把字体设置成你自己的字体资源即可。注意路径问题。
同时,TextMeshPro设置text的长度默认是8,但是当我们传入的字符串长度超出8时,会给我们新开辟一个数组,并赋值给原来的数组。详见TMPro_Private.cs 287行和792行。
4、使用到的工具
1)各种进制转换:http://jinzhi.supfree.net/
2)Unicode与中文的转换:http://app.baidu.com/2unicode
可以在工具2中将我们指定的汉字转为Unicode编码。16字节的16进制数,如\u6211,如果不足,在前面加FF,这个可以百度一下Unicode大小端的问题。然后使用工具1将上步转换成的16进制数转化为10进制数,即可在程序中打断点,找到这个key值是否包含在字体资源中。
5、字体资源的使用
使用该资源,不能通过public的方式拖拽,只可以用代码获取脚本的方式创建GameObject
如下:
首先包含命名空间using TMPro
private TextMeshPro m_Name;
private TextMeshPro m_Sign;
private GameObject headShowObj;
private GameObject headSignObj;
private Transform objTrans;
private Transform signTrans;
private Vector3 v = new Vector3(0,2.0f,0);
private Vector3 vs = new Vector3(0,2.5f,0);
headShowObj = new GameObject("playerName");
objTrans = headShowObj.transform;
objTrans.parent = _controller.trans;// Camera.main.transform;
objTrans.localPosition = Vector3.zero + v;
objTrans.localRotation = Quaternion.identity;
objTrans.localScale = Vector3.one;
objTrans.LookAt(Camera.main.transform.position);
m_Name = headShowObj.AddComponent<TextMeshPro>();
m_Name.font = Resources.Load ("UI/Fonts/SIMLI",typeof(TextMeshProFont)) as TextMeshProFont;
m_Name.fontSize = 4;
m_Name.isOverlay = true;
m_Name.alignment = AlignmentTypes.Center;
m_Name.anchor = AnchorPositions.Center;
m_Name.text = ”hehe“;
运行即可看到效果,其实不懂的可以详细看看上面提到的文档。