使用BMFont创建适用于Unity的艺术字

最近经常使用艺术字,虽然之前的工作经验我知道只需要修什么哪些就可以弄好艺术字的创建和间隔,所以打算做个总结,接下来分为以下几步(其中会有补充,最后会有如何解决unity艺术字的字距问题)

第1步 下载BMFont

去官网下载即可BMFont官网,解压,64位就运行64位的exe程序

第2步 生成fnt文件

这里以0-9的数字图片为例子,图片如下:

打开之后,打开Options->Exprot Options,修改字体输出设置

至于内边距和间距一般不用管,然后打开Edit->Open Image Manager,点击Image,三个选项从上到下分别是导入图片、编辑图片(需要点击选中某行)、删除图片(同前一样需要选中)

这里点击导入图片,选中你的图片,假设你选的字符是0,那么选择好图片后,出现了这个页面,检查路径没问题,接下来是填入替换字符的id

如下图,鼠标放到替换字符处,前面的第一个就是id,该id为48,确定之后,开始选中这些需要导出的字符,亮色的就是选中的,左下角有你选中字符数

然后输出即可

补充:

BMFont官网文档

第三步 使用unity生成字体文件(.fontsettings)

添加脚本(非本人所写,这是我觉得写的不错的一个脚本)

,使用也很简单,只需要把.fnt和生成的图集一起导入unity,然后是三个参数的导入,fnt文件拖入第一个框内,第二个可以直接省略,第三个也可以省略,然后直接点击生成,字体就会出现在和fnt文件同目录下

文章链接:https://blog.csdn.net/w0100746363/article/details/105637683

using System.Collections.Generic;
using System.IO;
using System.Xml;
using UnityEditor;
using UnityEngine;public class BMFont : EditorWindow
{private TextAsset _fontTextAsset;private Texture _fontTexture;private string _fontsDir;[MenuItem("FontTools/BMFont", false, 12)]private static void BMFontTools(){BMFont bmFont = new BMFont();bmFont.Show();}private string _getAssetPath(string path){string pathTemp = path.Replace("\\", "/");pathTemp = pathTemp.Replace(Application.dataPath, "Assets");return pathTemp;}void OnGUI(){EditorGUILayout.BeginVertical();TextAsset taTemp = EditorGUILayout.ObjectField("选择Font文件:", _fontTextAsset, typeof(TextAsset), true) as TextAsset;if (taTemp != _fontTextAsset && taTemp != null){string assetDir = Directory.GetParent(AssetDatabase.GetAssetPath(taTemp)).FullName;assetDir = _getAssetPath(assetDir);string imgPath = string.Format("{0}/{1}_0.png", assetDir, taTemp.name);_fontTexture = AssetDatabase.LoadAssetAtPath<Texture>(imgPath);_fontsDir = string.Format("{0}.fontsettings", Path.Combine(assetDir, taTemp.name));if (_fontTexture == null){_fontsDir = string.Empty;Debug.LogError(string.Format("未发现{0}文件", imgPath));}}_fontTextAsset = taTemp;_fontTexture = EditorGUILayout.ObjectField("选择Font图片文件:", _fontTexture, typeof(Texture), true) as Texture;GUI.enabled = false;_fontsDir = EditorGUILayout.TextField("字体生成路径:", _fontsDir);GUI.enabled = true;if (GUILayout.Button("Generate Font")){if (!string.IsNullOrEmpty(_fontsDir)){Material mat = AssetDatabase.LoadAssetAtPath<Material>(_fontsDir.Replace(".fontsettings", ".mat"));if (mat == null){mat = new Material(Shader.Find("UI/Default Font"));AssetDatabase.CreateAsset(mat, _fontsDir.Replace(".fontsettings", ".mat"));}if (_fontTexture != null){mat = AssetDatabase.LoadAssetAtPath<Material>(_fontsDir.Replace(".fontsettings", ".mat"));mat.SetTexture("_MainTex", _fontTexture);}else{Debug.LogError("贴图未做配置,请检查配置");return;}Font font = AssetDatabase.LoadAssetAtPath<Font>(_fontsDir);if (font == null){font = new Font();AssetDatabase.CreateAsset(font, _fontsDir);}_setFontInfo(AssetDatabase.LoadAssetAtPath<Font>(_fontsDir),AssetDatabase.GetAssetPath(_fontTextAsset),_fontTexture);font = AssetDatabase.LoadAssetAtPath<Font>(_fontsDir);font.material = mat;}else{Debug.LogError("创建失败,请检查配置");}}EditorGUILayout.EndVertical();}private void _setFontInfo(Font font, string fontConfig, Texture texture){XmlDocument xml = new XmlDocument();xml.Load(fontConfig);List<CharacterInfo> chtInfoList = new List<CharacterInfo>();XmlNode node = xml.SelectSingleNode("font/chars");foreach (XmlNode nd in node.ChildNodes){XmlElement xe = (XmlElement)nd;int x = int.Parse(xe.GetAttribute("x"));int y = int.Parse(xe.GetAttribute("y"));int width = int.Parse(xe.GetAttribute("width"));int height = int.Parse(xe.GetAttribute("height"));int advance = int.Parse(xe.GetAttribute("xadvance"));CharacterInfo info = new CharacterInfo();info.glyphHeight = texture.height;info.glyphWidth = texture.width;info.index = int.Parse(xe.GetAttribute("id"));//这里注意下UV坐标系和从BMFont里得到的信息的坐标系是不一样的哦,前者左下角为(0,0),//右上角为(1,1)。而后者则是左上角上角为(0,0),右下角为(图宽,图高)info.uvTopLeft = new Vector2((float)x / texture.width, 1 - (float)y / texture.height);info.uvTopRight = new Vector2((float)(x + width) / texture.width, 1 - (float)y / texture.height);info.uvBottomLeft = new Vector2((float)x / texture.width, 1 - (float)(y + height) / texture.height);info.uvBottomRight = new Vector2((float)(x + width) / texture.width, 1 - (float)(y + height) / texture.height);info.minX = 0;info.minY = -height;info.maxX = width;info.maxY = 0;info.advance = advance;chtInfoList.Add(info);}font.characterInfo = chtInfoList.ToArray();AssetDatabase.Refresh();}
}

其中代码最关键的部分就是BMFont的uv坐标转换到unity下的uv坐标,这里代码的意思也很简单就是循环取出图集中的每张图(制作fnt字体时不是有张图吗,那个就是图集),然后每张图转换uv坐标即可。

BMFont的uv坐标,左上角(0,0),右下角为(宽度,高度)

Unity的uv坐标,左下角(0,0),右上角(1,1)

计算就如下图(自己打的手稿哈哈)

UV坐标是建立在一张图(纹理)上的。UV坐标是一个二维坐标系统,用于指定纹理图像上的具体位置,以便将纹理映射到三维模型的表面或二维图形上。这里的“一张图”指的是纹理图像,它包含了将要被映射的像素数据。

uv坐标参考博客:

Unity里的UV到底是什么 - cancantrbl - 博客园

Unity中Mesh的uv坐标讨论与使用方法_unity mesh uv-CSDN博客

解决unity艺术字的字距

通过 Tracking 设置可修改每个字符与同一行下一个字符的接近程度,而通过 Line spacing 设置可定义每行与下一行的接近程度

了解Font文件:Unity官网文档

注意

修改Tracking后需要运行(重新编译后才会生效)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/889417.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

websocket_asyncio

WebSocket 和 asyncio 指南 简介 本指南涵盖了使用 Python 中的 websockets 库进行 WebSocket 编程的基础知识&#xff0c;以及 asyncio 在异步非阻塞 I/O 中的作用。它提供了构建高效 WebSocket 服务端和客户端的知识&#xff0c;以及 asyncio 的特性和优势。 1. 什么是 WebS…

数据结构_树表的查找

平衡调整方法 四种类型的调整 LL型调整 RR型调整 LR型调整 RL型调整 // 以p为根的二叉排序树作右旋处理(LL void BST::rRotate(BiNode*& p) {BiNode* k p->lChild;p->lChild k->rChild;k->rChild p;p k; }// 以p为根的二叉排序树作左旋处理(RR void BST:…

更新数据时Redis的操作

一般做法是在数据库更新后删除Redis中对应的缓存数据&#xff0c;而非更新数据。那么为什么要这么做呢&#xff1f; 以下是一些拙见 场景使用 金融交易系统&#xff1a;在金融领域&#xff0c;数据的准确性至关重要。任何数据不一致都可能导致严重的财务损失。因此&#xff0…

51c~Pytorch~合集2

我自己的原文哦~ https://blog.51cto.com/whaosoft/11878447 一、PyTorch与torch-xla的桥接 文章从XLATensor开始的溯源、注册PyTorch库实现、从PyTorch调用到torch_xla三个方面来介绍PyTorch与torch-xla的桥接 XLA (Accelerated Linear Algebra)是一个开源的机器学习编…

TMS320C55x DSP芯片结构和CPU外围电路

第2章 DSP芯片结构和CPU外围电路 文章目录 第2章 DSP芯片结构和CPU外围电路TMS320C55x处理器的特点TMS320c55x CPU单元指令缓冲(Instruction Buffer Unit) I单元程序流程(Program Flow Unit) P单元地址数据(Address-data Flow Unit) A单元数据计算(Data Computation Unit) D单元…

实战攻防中针对JS路径的泄露和Webpack漏洞的初探

0x1前言 浅谈 这篇文章给师傅们分享下前段时间跟其他师傅学习和交流的Webpack相关漏洞&#xff0c;这个漏洞相对来说比较冷门&#xff0c;在web漏洞中不是那么的热度高&#xff0c;但是平常去挖掘和发现这个漏洞相对来说还是不难的。 后面要是有机会可以给师傅们分享下油猴的…

【人工智能基础08】卷积神经网络习题:卷积神经网络计算、图像填充、卷积的表达与设计

文章目录 1. 卷积核计算2. 卷积神经网络计算3. 卷积核关注的特征问题解答水平边缘检测与水平条纹检测45度条纹检测 4. 图像检测5. 卷积网络是特殊的全连接网络6. 输出矩阵的三种填充方法7. 卷积设计8.9 成像公式10. 卷积的计算次数11. 全连接层的计算 1. 卷积核计算 卷积操作过…

音乐网站设计与实现

文末获取源码和万字论文&#xff0c;制作不易&#xff0c;感谢点赞支持。 音乐网站设计与实现 摘 要 本音乐网站是针对目前音乐网站管理的实际需求&#xff0c;从实际工作出发&#xff0c;对过去的音乐网站管理系统存在的问题进行分析&#xff0c;结合计算机系统的结构、概念、…

【机器学习】在向量的流光中,揽数理星河为衣,以线性代数为钥,轻启机器学习黎明的瑰丽诗章

文章目录 线性代数入门&#xff1a;机器学习零基础小白指南前言一、向量&#xff1a;数据的基本单元1.1 什么是向量&#xff1f;1.1.1 举个例子&#xff1a; 1.2 向量的表示与维度1.2.1 向量的维度1.2.2 向量的表示方法 1.3 向量的基本运算1.3.1 向量加法1.3.2 向量的数乘1.3.3…

SpringBoot——分层解耦、IOC、依赖注入

三层架构 如下图&#xff0c;创建Dao的接口以及该接口的实现类&#xff0c;Service也一样 Dao // Dao接口 public interface UserDao {public List<String> findAll(); }// Dao接口的实现 public class UserDaoImpl implements UserDao {// 加载用户数据Overridepublic …

【数据结构——栈和队列】括号配对(头歌实践教学平台习题)【合集】

目录&#x1f60b; 任务描述 相关知识 测试说明 我的通关代码: 测试结果&#xff1a; 任务描述 本关任务&#xff1a;编写一个程序利用栈判断左、右圆括号是否配对。 相关知识 为了完成本关任务&#xff0c;你需要掌握&#xff1a;栈对括号的处理。 栈对括号的处理 &…

企业级日志分析系统ELK之ELK概述

ELK 概述 ELK 介绍 什么是 ELK 早期IT架构中的系统和应用的日志分散在不同的主机和文件&#xff0c;如果应用出现问题&#xff0c;开发和运维人员想排 查原因&#xff0c;就要先找到相应的主机上的日志文件再进行查找和分析&#xff0c;所以非常不方便&#xff0c;而且还涉及…

js后端开发之Next.js、Nuxt.js 与 Express.js

后端js之Next.js、Nuxt.js 与 Express.js 在现代 Web 开发中&#xff0c;JavaScript 已经成为前后端通用的编程语言&#xff0c;而选择合适的后端框架则是构建高效、可扩展应用程序的关键。本文将带你深入了解三个流行的 JavaScript 后端框架&#xff1a;Next.js、Nuxt.js 和 …

CSS的2D和3D动画效果

CSS的2D和3D动画效果&#xff1a;网页动态设计的魔法 在现代网页设计中&#xff0c;动画已经成为提升用户体验的重要元素。通过引入动态效果&#xff0c;我们不仅可以使交互更加流畅和直观&#xff0c;还能吸引用户的注意力&#xff0c;增强品牌认知度。CSS提供了强大的工具&a…

离开wordpress

wordpress确实挺好用的 插件丰富 主题众多 收费的插件也很多 国内的做主题的也挺好 但是服务器跑起来各种麻烦伤脑筋 需要花在维护的时间太多了 如果你的网站持续盈利 你就会更担心访问质量访问速度 而乱七八糟的爬虫黑客 让你的服务器不堪重负 突然有一天看到了静态站…

pyqt+ubuntu18.04+designer+测试是否安装成功

引用&#xff1a; Ubuntu Linux安装PyQt5并配置Qt Designer 在Visual Studio Code中使用PyQt5开发python GUI应用程序 Linux环境下在Vscode中安装和设置PyQt5插件 其中&#xff0c; 测试是否安装成功 1、设置好之后在vscode编辑器的左侧文件目录栏空白位置右键&#xff0…

系统启动优化首笔交易慢优化

系统启动优化 1. 启动耗时原因&#xff1a; bean加载文件&#xff0c;资源&#xff0c;配置扫描加载其它&#xff08;网络通讯&#xff0c;GC等&#xff09; 2. 优化手段 扫描路径尽可能精确关闭swagger扫描bean加载使用懒加载&#xff08;Lazy&#xff09;升级jdk&#xff0…

Apache Doris 3.0.3 版本正式发布

亲爱的社区小伙伴们&#xff0c;Apache Doris 3.0.3 版本已于 2024 年 12 月 02 日正式发布。 该版本进一步提升了系统的性能及稳定性&#xff0c;欢迎大家下载体验。 GitHub 下载&#xff1a;https://github.com/apache/doris/releases 官网下载&#xff1a;Apache Doris - D…

torchaudio.load 段错误

使用 torchaudio.load 时出现崩溃&#xff0c;如图 解决&#xff1a; 安装 ffmpeg ​conda install ffmpeg -c conda-forge 尝试但没解决问题的方法包括 重装 cuda&#xff0c;重装 pytorch&#xff0c;安装 PySoundFile、SoundFile、sox。

介绍一下CSS中伪类和伪元素的概念

一、伪类&#xff08;Pseudo - Classes&#xff09; 1. 定义 伪类是添加到选择器的关键字&#xff0c;用于定义元素的特殊状态。这些状态不是由文档树中的结构或属性来表示&#xff0c;而是基于用户行为&#xff08;如鼠标悬停&#xff09;、元素状态&#xff08;如被选中&am…