【UE】在UMG中引入Web矢量图标库,彻底告别找图切图。再做一个可视化检索工具
在开发 UE UI 时,我们经常需要海量的高清图标。与其到处找图、切图、做PaperSprite优化。
不如直接引入前端 Web 开发中常用的矢量图标库。这类图标不仅资源丰富,而且打包成字体后体积极小、无限放大不失真。
本文将演示如何将开源 SVG 图标库转换为 UE 字体资产,并进阶制作一个编辑器控件,实现图标的可视化检索与一键复制。
一、 准备图标
1. 找到图标库
首先找到一个高质量的开源图标库。这种图标在 HTML/CSS 中有大量应用,资源极多。
[一个很华丽的图标库]
[一个很商业的图标库]
(这里应该列举一些开源库,但是我太懒了,有空整理)
2. 下载 SVG 库
以下教程以开源免费的图标库Reicon为例。
可以看到它有Outline 轮廓和Filled 填充两种样式,非常适合作为教程案例:
无论选择如何,找到并下载打包的 SVG 格式:
解压文件后,可以看到官方已经按样式分好了两个文件夹:
里面包含的就是独立的 SVG 格式图标:
二、 将 SVG 转换为字体
这里我们使用主流的在线SVG Editor工具将这堆图片打包成字体文件。
前往:Icomoon
1. 新建项目
在左上角New (新建)一个项目并点击Load (载入):
2. 导入 SVG
在Import 导入中点击Select 选择按钮。
找到本地目录。注意:一次只导入一个样式!我们先导入 Outline 的:
Ctrl+A全选所有 SVG,确认导入。
3. 生成并下载 Font
等待上传完成,在右侧就可以看到所有图标了。为了后续使用顺利,不要改变默认顺序。
- 点击Export进入导出界面
- 选择下载到本地
- Formals只保留Font
- 点击Download下载
下载完成并解压,将解压后的文件夹改名为"样式"outline以作区分。
4. 转换其余样式
重复前面的步骤,将剩余的样式(如 Filled)也转换完成。
现在,这个图标库的两种样式都已经打包成了字体文件:
三、 导入 UE 并在 UMG 中使用
1. 整理字体文件
第一步:导入字体
每个样式的文件夹中,都会包含以下文件:
进入fonts文件夹,将里面的.ttf文件修改为字体名_样式名(例如Reicon_Outline.ttf)。在虚幻引擎中,我们只需要这个.ttf格式的字体文件。
2. 导入字体资产
将第一个样式的.ttf直接拖入 UE 内容浏览器,引擎会弹窗询问是否同时创建 Font 资产,点击“Yes”。
这样引擎会同时建立Font (字体)和Font Face (字体样式)两个资产。
💡 字体和字体样式的关系类比:
- Font(字体):对应宏观上的名字,如
微软雅黑- Font Face(样式):对应具体的文件表现,如
微软雅黑_斜体,微软雅黑_粗体
为它们重命名以保持工程整洁:
接下来导入其余样式的.ttf文件,这次弹窗全部选“否 (No)”(只生成 Font Face)。
最终的效果是:一个通用字体资产(Font),携带了多个样式资产(Font Face)。
3. 配置字体资产
双击打开主Font资产,点击+ (添加字体),将刚导入的其他样式(如 Filled)添加进去,并在双击命名以作区分。
双击名字重命名
4. 验证与手动测试
双击打开字体后,默认显示各种空白占位符是完全正常的,因为这些图标所在的 Unicode 编码通常落在\uE900等非公开的特殊字符区间里。
怎么找到需要的图标字符呢?
回到 Icomoon 下载的字体包中,找到demo.html并用浏览器打开。
在网页List of Glyphs下拉菜单中选择character。
直接点击你想要的图标,它就会以“字符”的形式自动复制到你的系统剪切板。
回到 UE,在 UMG 中新建一个TextBlock (文本)控件,将字体指定为刚才设置的 Reicon 字体,在文本框里Ctrl + V粘贴,图标就完美显现了!
四、 高阶:制作可视化编辑器控件
对于普通项目,到第三步就已经可以正常使用了。
但作为追求效率的开发者,我不希望每次找图标都要在引擎外部切到html网页里去复制。如果能将这个庞大的图标库集成成引擎内部的通用底层资产,就可以一劳永逸。
因为有近千个图标,手动配置枚举是不可能的。我们需要把demo.html里的数据提取成 UE 能读的数据表(Data Table),然后利用编辑器实用控件(Editor Utility Widget)用蓝图自动生成一个可视化面板。
1. 提取并构建数据字典
1.1 将 HTML 数据一键转为 CSV 表格
审查demo.html的源码,发现它自带了一个非常完美的字典,记录了十六进制编码与图标名称的映射:
constnames={0xf000:"volume-slash2",...}我们可以通过浏览器控制台,用几行 JavaScript 代码把它变成 UE 直接可用的 CSV 表格。
由于油猴脚本无法处理本地文件,因此直接使用开发者控制台。
- 用浏览器打开
demo.html。 - 按
F12打开开发者工具,点击Console (控制台)标签。 - 复制以下 JavaScript 代码,粘贴到控制台并回车:
letcsvContent="---,IconName,IconChar\n";letrowIndex=1;for(const[hexCode,iconName]ofObject.entries(names)){// 把编码转成 Unicode 字符letactualChar=String.fromCharCode(hexCode);csvContent+=`${rowIndex},${iconName},${actualChar}\n`;rowIndex++;}constblob=newBlob([csvContent],{type:'text/csv;charset=utf-8;'});constlink=document.createElement("a");link.href=URL.createObjectURL(blob);link.download="ReiconData.csv";link.click();(F12 控制台输入位置演示)
运行后,浏览器会自动下载一个ReiconData.csv文件。这才是我们真正的数据源。
1.2 在虚幻引擎中建立数据结构
1.2.1 创建结构体 (Struct)
在内容浏览器右键 -> Blueprints ->Structure,命名为
F_IconData。添加两个变量:
IconName(String) 和IconChar(String)。
1.2.2 导入 CSV 创建数据表 (Data Table)
把刚才下载的
ReiconData.csv拖进 UE。导入类型选择Data Table,
行类型 (Row Type)选择刚创建的F_IconData。打开生成的数据表,图标的名字和真实字符已经整整齐齐躺在里面了。
2. 开发可视化编辑器控件
⚠️ 性能警告:因为图标数量巨大,绝对不能使用普通的垂直框或 Wrap Box 直接生成所有 UI,否则一打开工具 UE 瞬间卡死。我们必须使用支持内存虚拟化的Tile View (瓦片视图)。
Tile View 工作流需要准备两个核心组件:
Item Data:纯数据载体(下文命名为ListData_IconFont)Entry Widget:视觉表现按钮(下文命名为ListButton_IconFont)
2.1 制作 Tile View 的子项
2.1.1 制作数据载体 (ListData_IconFont)
- 新建蓝图,继承自原生
Object,命名为ListData_IconFont。 - 在其中新建一个变量
IconData,类型选为我们建立的结构体F_IconData,并勾选“生成时公开 (Expose on Spawn)”。
2.1.2 制作按钮表现控件 (ListButton_IconFont)
创建一个新的编辑器控件 (Editor Utility Widget),命名为
ListButton_IconFont。摆放按钮和文本。为文本指定刚才的 Reicon 字体。(小技巧:文字外嵌套一个画布面板/Overlay,可以使文字绝对居中悬浮于按钮上方,避免被按钮尺寸挤压。)
- 在类设置 (Class Settings) 中,实现接口
User Object List Entry。
双击接口生成的
Event On List Item Object Set进行重写。传进来的Object就是咱们刚刚做的ListData_IconFont直接一个Cast上去,给丫把魂都Get出来
提取后,将字符直接 Set 给文本控件。
点击拷贝的具体按钮事件,等主面板做完再回来连。
2.2 组装最终的主编辑器控件
2.2.1 UI 布局
- 右键创建一个新的 Editor Utility Widget,命名为
EU_IconFont。
- 拖入一个
Tile View (瓦片视图)。在属性的 Entry Widget Class 里,指定刚才做的ListButton_IconFont。
- 在左侧设计一个预览区域(两个文本框分别显示大图标和名字)。
关键点:预览的 Icon 文本建议使用可编辑文本 (Editable Text),这样一旦选中它,你就可以直接高亮并Ctrl + C复制字符了。
2.2.2 蓝图逻辑整合
建立回调桥梁:回到
ListData_IconFont(数据蓝图),新增一个变量EU_IconFont,类型设为刚建的主控件引用,同样勾选生成时公开。主面板初始化逻辑:在
EU_IconFont的Construct事件中,读取数据表:
- 读取数据表,循环构建
ListData_IconFont对象并填入数据。同时把自己 (Self) 传进去,以便后续跨蓝图通信。 - 将构建好的对象存入数组,并最终交由 TileView
Set List Items。 - 记得在重建列表前先 Clear 数组。
实现跨蓝图交互反馈:在主面板
EU_IconFont中,新建一个自定义事件(如ButtonClicked),专门接收子按钮传回的数据。完善子按钮点击:再次进入
ListButton_IconFont。在按钮的OnClicked事件中,从获取到的 Data 对象里拉出主面板引用,调用刚建好的自定义事件,把数据送回主面板EU_IconFont。更新主面板 UI:回到主面板
EU_IconFont,在接收到事件后,将传回的 IconChar 和名字更新到左侧的预览区文本框中。
五、 大功告成
1. 运行
现在,直接右键点击你的EU_IconFont,选择Run Editor Utility Widget (运行编辑器工具控件)
点开界面,图标呈现在眼前:
点击任意图标,左侧预览区立即更新。直接选中左侧的可编辑文本框,复制字符走人。
- 只要这样那样,就可以成通用工具:
2. 自动复制到剪切板
如果你的工程中正好安装了FileSDK插件,可以直接在ListButton_IconFont的按钮点击事件中,调用该插件自带的剪切板节点,一步到位实现“点击即复制”的功能:
六、继续堆料!
因为在文章最后带了货,于心不忍于是再继续把功能推进几步
1. 搜索
那么多图标找起来很麻烦吧?接下来制作一个搜索框 :
- 首先放置一个
EditableTextBox,并绑定时事件,当文本修改时触发 - 在此处增加判断,输入为
空时不进行判断,当有输入时判断IconName是否含有字符
2. 历史
- 再放置一个
EditableTextBox,用来显示历史,我们将功能写在这里 - 这个
EditableTextBox的字体,要使用我们制作的字体,效果如下
请我喝咖啡
正文到这里就结束了,最后厚颜无耻地给自己的蓝图扩展插件打个广告。
Node Source
平时翻看大项目连线或者排查魔鬼意大利面时,最头疼的就是找不到节点到底是从哪封装出来的。
插件的功能非常纯粹,就是能在蓝图节点上直观地显示出它究竟来自何方(比如哪个特定的子系统、类或全局函数库)。
对于经常在各类上下文、隐藏节点里迷失的蓝图重度用户来说,绝对能帮你省下大把搜寻底层的时间。
如果你觉得有用,欢迎体验和安利!
原来你是
FileSDK带的节点啊
