Unity的UGUI中使用CustomFont(BMFont)
来源:互联网 发布:淘宝返利网哪个最好 编辑:程序博客网 时间:2024/05/21 11:39
Unity的UGUI的文字渲染效率应该是挺高的,一般来说用默认的Text控件,TTF的Font就满足需求了。不过有时候需要渲染艺术字体的时候还是需要用到BMFont。
一、BMFont的基础使用,创建fnt字体的步骤就不多说了。这里额外提一下就是BMFont是支持命令行的。这里贴一下我使用的脚本,更新字体比较方便。
bmfc文件是BMFont的配置文件,使用BMFont的GUI程序设置并保存好对应的字体配置(配置里面包含纹理大小、特殊字符对图片的映射关系等等)
txt文件是一个纯文本,包含所需要生成字体的所有文字
# -*- coding: utf-8 -*-import os,sys,shutil,subprocess,globglobal SOURCE_PATHglobal TARGET_PATHSOURCE_PATH = 'font/'TARGET_PATH = '../Assets/Font'COMMON_TEXT = "text.txt"CMD = 'support/BMFont/bmfont.exe'def genFont(configPath, txtPath): fntPath = configPath.replace('.bmfc', '.fnt'); pngPathOld = configPath.replace('.bmfc', '_0.png'); pngPathNew = configPath.replace('.bmfc', '.png'); subprocess.call('"{0}" -c {1} -o {2} -t {3}'.format(CMD, configPath, fntPath, txtPath)) if os.path.exists(pngPathNew): os.remove(pngPathNew); os.rename(pngPathOld, pngPathNew); fileData = [] fp = open(fntPath, 'r'); for line in fp: if line.find('file="') != -1: fileData.append(line.replace('_0.png', '.png')); else: fileData.append(line); fp.close(); fpw = open(fntPath, 'w'); fpw.writelines(fileData);fileList = glob.glob(SOURCE_PATH + '*.bmfc')for file in fileList: txtFile = file.replace(".bmfc", ".txt") if os.path.exists(txtFile): genFont(file, txtFile) else: genFont(file, COMMON_TEXT)os.system('PAUSE')
二、Unity中的特殊字体是使用CustomFont。 CustomFont是一个资源,跟ttf字体等价,里面包含了字体的字形信息等数据。之前NGUI有一套脚本可以通过fnt文件创建CustomFont。 我写了一个脚本用来做类似的事情。
using UnityEngine;using UnityEditor;using System.Collections.Generic;using System.IO;using System.Text.RegularExpressions;// 创建bmfontpublic class CreateFontEditor : Editor{ [MenuItem("Assets/CreateBMFont")] static void CreateFont() { Object obj = Selection.activeObject; string fntPath = AssetDatabase.GetAssetPath(obj); if (fntPath.IndexOf(".fnt") == -1) { // 不是字体文件 return; } 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 = 0; int texWidth = 1; int texHeight = 1; while (line != null) { if (line.IndexOf("char id=") != -1) { 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 = 1 - (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 / 2; // 这样调出来的效果是ok的,原理未知 info.glyphWidth = width; info.glyphHeight = -height; // 同上,不知道为什么要用负的,可能跟unity纹理uv有关 info.advance = xadvance; charList.Add(info); } } else if (line.IndexOf("scaleW=") != -1) { 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); }}
这里稍微解释一下,最终的Font字体,我是先手动在Unity里面创建一个CustomFont文件,名字跟fnt文件相同,并给它附上相应的Material,Material是一个材质,shader选择 GUI/Text Shader,图片选择BMFont生成的纹理。 这里稍作修改可以支持自动创建字体文件。
这个脚本干的事情就是读取并解析fnt文件,获取每个字形的坐标,创建CharactorInfo对象并给它附上计算后的uv坐标,最终结果保存早Font里面。需要留意的是unity的uv坐标是左下角为原点。
1 0
- Unity的UGUI中使用CustomFont(BMFont)
- UGUI中CustomFont字体使用与制作
- 【Unity】UGUI 如何使用CustomFont(自定义字体)
- unity uGui使用图片显示数字(CustomFont)记录备忘
- UGUI 使用BMFont
- unity NGUI中使用bmfont制作的字体图集
- UGUI中使用位图艺术字(使用BMfont的两种方式)
- [Unity UGUI] use image display Numbers (CustomFont) to record notes
- unity 3d中使用BMFont制作NGUI清晰字体
- unity 3d中使用BMFont制作清晰字体
- unity 3d中使用BMFont制作清晰字体
- unity 3d中使用BMFont制作NGUI清晰字体
- unity 3d中使用BMFont制作清晰字体
- Unity中UGUI的部分控件的使用
- Unity的UGUI中使用ETC1+Alpha的格式
- Unity的UGUI中使用ETC1+Alpha的格式
- Unity的UGUI中使用ETC1+Alpha的格式
- Unity中使用UGUI与ScrollView的练习
- Hello Markdown
- C++控制台循环链表实现贪吃蛇
- CSS选择器
- Linux启动流程图
- ListView的列表项中含有CheckBox之类的抢占焦点的组件使得ListView本身失去焦点的解决方法
- Unity的UGUI中使用CustomFont(BMFont)
- 杭电Sort it 2689树状数组
- 贪吃蛇
- Codeforces Round #332 (Div. 2) A. Patrick and Shopping
- centos 7 安装源码kernel source(源码树)编译驱动
- 内存管理的一些小问题(面试常用)
- 关于kettle 与mysql 连接后 出现错误的问题
- How to configuration physical dataguard within an Exadata?
- css优先级和权重