【Unity编辑器扩展】艺术字/自定义图片字体生成工具

艺术字在游戏中很常用,由于普通字体样式过于平淡,制作花里胡哨的文字图片作为游戏字体使用,这就是艺术字。

不依赖第三方工具,仅使用Unity自带的Custom Font + 一张艺术字图集就能实现这个功能,但是为了便于使用,还需要依赖自动化工具,自动化把字符映射到图片纹理坐标,一键生成字体文件。

工具使用效果:

 字符对齐图片:

 艺术字使用效果:

Unity自定义字体参数面板如下:

 其中Character Rects数组是每个字符所在贴图的uv坐标系下的映射Rect:

Index:字符的Ascii码偏移值;字符真实ASCII码 = Ascii Start Offset + Index;这里建议把ASCII码起始值(Ascii Start Offset)设为0,把Index直接设置为字符的ASCII码。

Vert:字符的宽高信息, Y为高度的一半是为了垂直方向居中;

工具功能设计:

0. 首先,制作字符集图片,在Unity中用Sprite Editor进行自动Sprite碎图分割;

1. 拖拽添加字符图集;

2. 设置字符文件或直接在输入框输入字符,两处字符将自动合并去重;

3. 支持设置字体大小;自定义字体无法通过Text组件动态修改字体大小,因此需要为不同字号生成单独的字体文件,但材质和贴图共用,只消耗一个DC;

4.支持字符与图集对照预览;

5. 点击生成,一键创建字体文件和对应材质;

代码实现:

代码实现非常简单,主要就是读取Sprite中的子图Rect信息,然后转换到字体所需的UV坐标系Rect等;

使用Unity 2022新版Sprite编辑器API读取碎图信息:

            var texFact = new SpriteDataProviderFactories();texFact.Init();var texDataProvider = texFact.GetSpriteEditorDataProviderFromObject(texture2d);texDataProvider.InitSpriteEditorDataProvider();var spriteRects = texDataProvider.GetSpriteRects();

生成字体文件的Character Rects:

private bool ParseCharsInfo(char[] chars, out CharacterInfo[] charInfoArr, out Texture2D charsTexture){charInfoArr = null;charsTexture = null;if (chars == null || chars.Length < 1){return false;}charsTexture = OwnerEditor.SelectObjectList[0] as Texture2D;var texSize = new Vector2Int(charsTexture.width, charsTexture.height);var texFact = new SpriteDataProviderFactories();texFact.Init();var texDataProvider = texFact.GetSpriteEditorDataProviderFromObject(charsTexture);texDataProvider.InitSpriteEditorDataProvider();var spRects = texDataProvider.GetSpriteRects();int count = Mathf.Min(chars.Length, spRects.Length);charInfoArr = new CharacterInfo[count];for (int i = 0; i < count; i++){var spRect = spRects[i].rect;var uvMin = spRect.min / texSize;var uvMax = spRect.max / texSize;float fontHeight = m_FontSize;float fontScale = m_FontSize / spRect.height;charInfoArr[i] = new CharacterInfo{index = chars[i],uvBottomLeft = uvMin,uvBottomRight = new Vector2(uvMax.x, uvMin.y),uvTopLeft = new Vector2(uvMin.x, uvMax.y),uvTopRight = uvMax,minX = 0,minY = -(int)(fontHeight * 0.5f),//居中偏移量advance = (int)(spRect.width * fontScale),glyphWidth = (int)(spRect.width * fontScale),glyphHeight = (int)fontHeight,};}return true;}

生成字体文件:

string outputDir = EditorUtility.SaveFolderPanel("保存到", Application.dataPath, null);if (!string.IsNullOrWhiteSpace(outputDir) && Directory.Exists(outputDir)){outputDir = Path.Combine("Assets", Path.GetRelativePath(Application.dataPath, outputDir));string outputFont = Path.Combine(outputDir, $"{charsTexture.name}_{m_FontSize}.fontsettings");Font newFont;if (!File.Exists(outputFont)){newFont = new Font(charsTexture.name);AssetDatabase.CreateAsset(newFont, outputFont);}newFont = AssetDatabase.LoadAssetAtPath<Font>(outputFont);string outputFontMat = Path.Combine(outputDir, $"{charsTexture.name}.mat");if (!File.Exists(outputFontMat)){var tempFontMat = new Material(Shader.Find("UI/Default Font"));AssetDatabase.CreateAsset(tempFontMat, outputFontMat);}var fontMat = AssetDatabase.LoadAssetAtPath<Material>(outputFontMat);fontMat.shader = Shader.Find("UI/Default Font");fontMat.SetTexture("_MainTex", charsTexture);EditorUtility.SetDirty(fontMat);AssetDatabase.SaveAssetIfDirty(fontMat);newFont.material = fontMat;newFont.characterInfo = charInfoArr;EditorUtility.SetDirty(newFont);AssetDatabase.SaveAssetIfDirty(newFont);Selection.activeInstanceID = newFont.GetInstanceID();}

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

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

相关文章

【机器学习】二、决策树

目录 一、决策树定义&#xff1a; 二、决策树特征选择 2.1 特征选择问题 2.2 信息增益 2.2.1 熵 2.2.2 信息增益 三、决策树的生成 3.1 ID3算法 3.1.1理论推导 3.1.2代码实现 3.2 C4.5 算法 3.2.1理论推导 ​ 3.2.2代码实现 四、决策树的剪枝 4.1 原理 4.2 算法思路&#xff1a…

uniapp循环对象列表---点击列表切换选中不同状态

目录 源码图片最后 源码 <template><view><ul><li v-for"(item, index) in list" click"toggleSelection(index)" :class"{selected: selectedIndex index}">{{ item }}<view :class"{selected: selectedInde…

【Linux】 ps 命令使用

ps &#xff08;英文全拼&#xff1a;process status&#xff09;命令用于显示当前进程的状态&#xff0c;类似于 windows 的任务管理器。 语法 ps [选项] ps命令 -Linux手册页 著者 ps最初由布兰科兰克斯特撰写<lankestefwi.uva.nl>。迈克尔K约翰逊<johnsonmred…

【强化学习】15 —— TRPO(Trust Region Policy Optimization)

文章目录 前言TRPO特点策略梯度的优化目标使用重要性采样忽略状态分布的差异约束策略的变化近似求解线性搜索算法伪代码广义优势估计代码实践离散动作空间连续动作空间 参考 前言 之前介绍的基于策略的方法包括策略梯度算法和 Actor-Critic 算法。这些方法虽然简单、直观&…

【Java 进阶篇】Java ServletContext功能:获取文件服务器路径

Java ServletContext是Java EE中的一个核心接口&#xff0c;用于与Servlet容器进行通信&#xff0c;提供了许多有用的功能&#xff0c;包括获取文件服务器路径。在本文中&#xff0c;我们将详细介绍如何使用ServletContext来获取文件服务器路径&#xff0c;并提供示例代码以帮助…

Docker Tomcat 搭建文件服务器

本文基于openwrt上进行。 步骤 1: 安装 Docker 如果尚未安装Docker&#xff0c;首先需要安装Docker。根据你的操作系统&#xff0c;参考Docker官方文档来完成安装, 这里不做详细介绍。 步骤 2: 拉去docker Tomcat镜像 进入openwrt管理界面&#xff0c;docker选项中 拉取最新…

【移远QuecPython】EC800M物联网开发板的内置GNSS定位获取(北斗、GPS和GNSS)

【移远QuecPython】EC800M物联网开发板的内置GNSS定位获取&#xff08;北斗、GPS和GNSS&#xff09; 测试视频&#xff08;其中的恶性BUG会在下一篇文章阐述&#xff09;&#xff1a; 【移远QuecPython】EC800M物联网开发板的内置GNSS定位的恶性BUG&#xff08;目前没有完全的…

【华为OD题库-018】AI面板识别-Java

题目 Al识别到面板上有N(1<N≤100)个指示灯&#xff0c;灯大小一样&#xff0c;任意两个之间无重叠。由于AI识别误差&#xff0c;每次识别到的指示灯位置可能有差异&#xff0c;以4个坐标值描述Al识别的指示灯的大小和位置(左上角x1,y1&#xff0c;右下角x2.y2)。请输出先行…

三、IPSec VPN原理

IPSec 1、IPSec起源和定义2、IPSec原理2.1、IPSec协议框架2.1.1、安全联盟2.1.2、安全协议2.1.3、安全协议报文头结构2.1.4、封装模式2.1.5、加密和验证2.1.6、IKE安全机制 2.2、IPSec基本原理2.2.1、定义IPSec保护的数据流2.2.2、IKEv2协商安全联盟的过程 2.3、IPSec增强原理2…

uniapp之actionsheet 自定义组件

uniapp本身自带的actionsheet太丑&#xff0c;不够美观。闲着也是闲着&#xff0c;自己实现了一个类似的选择器。 支持功能&#xff1a; 1、左对齐 2、右对齐 3、居中 4、可加图标 下面贴出使用教程&#xff1a; <template><view><action-sheet alignment&…

go测试库之apitest

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

JavaSE基础 --- 类与对象

1.类与对象的定义 类是一种抽象的数据类型&#xff0c;它描述了一类对象的行为和状态。例如&#xff0c;我们可以定义一个名为“Dog”的类&#xff0c;它描述了狗这类动物的一般特性&#xff0c;如颜色、品种等状态&#xff0c;以及跑、叫等行为。 对象则是类的实例&#xff0c…

Java——接口类和抽象类的方法声明不需要加{}

在Java中&#xff0c;接口类和抽象类的方法声明是不需要加{}的。具体来说&#xff1a; 1. 接口类&#xff08;Interface&#xff09;&#xff1a;接口类定义了一组方法的规范&#xff0c;没有具体的方法实现。在接口中&#xff0c;方法声明只包含方法名、参数列表和返回类型&a…

两分钟搞定MySQL安装——极速mysql5.7安装教程

一、下载mysql mysql官网传送带&#xff1a; MySQL :: Download MySQL Community Server 选择好版本后直接下载即可&#xff0c;版本格式为zip格式。 二、安装mysql 1、解压zip安装包 ps&#xff1a;解压缩的路径里面不要出现中文哦&#xff01; 2、设置配置文件 新建data…

dubbo没有找到生产者

1、没有找到生产者 com.alibaba.dubbo.rpc.RpcException: No provider available from registry 127.0.0.1:2181 for service .... , please check status of providers(disabled, not registered or in blacklist)2、 查看是不是 对应的providers 没有 注册上去 找到 zk 对应…

解决爬虫在重定向(Redirect)情况下,URL没有变化的方法

重定向是一种网络服务&#xff0c;它可以实现从一个网页跳转到另一个网页的功能。它把用户请求的网页重定向到一个新的位置&#xff0c;而这个位置可以是更新的网页&#xff0c;或最初请求的网页的不同版本。另外&#xff0c;它还可以用来改变用户流量&#xff0c;当用户请求某…

内网穿透Windows下快速搭建个人WEB项目无需服务器

&#x1f4d1;前言 本文主要是windows下内网穿透文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日一句&#xff1a;努力…

HTML、CSS和JavaScript,实现换肤效果的原理

这篇涉及到HTML DOM的节点类型、节点层级关系、DOM对象的继承关系、操作DOM节点和HTML元素 还用到HTML5的本地存储技术。 换肤效果的原理&#xff1a;是在选择某种皮肤样式之后&#xff0c;通过JavaScript脚本来加载选中的样式&#xff0c;再通过localStorage存储。 先来回忆…

MYSQL 8.0 配置CDC(binlog)

CDC&#xff08;Change Data Capture&#xff09;即数据变更抓取&#xff0c;通过源端数据源开启CDC&#xff0c;ROMA Connect 可实现数据源的实时数据同步以及物理表的物理删除同步。这里介绍通过开启Binlog模式CDC功能。 注意&#xff1a;1、使用MYSQL8.0及以上版本。 2、不…

剑指JUC原理-9.Java无锁模型

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&…