【UE】在UMG中引入Web矢量图标库,彻底告别找图切图。再做一个可视化检索工具

【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

等待上传完成,在右侧就可以看到所有图标了。为了后续使用顺利,不要改变默认顺序

  1. 点击Export进入导出界面
  2. 选择下载到本地
  3. Formals只保留Font
  4. 点击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 表格。

由于油猴脚本无法处理本地文件,因此直接使用开发者控制台。

  1. 用浏览器打开demo.html
  2. F12打开开发者工具,点击Console (控制台)标签。
  3. 复制以下 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 工作流需要准备两个核心组件:

  1. Item Data:纯数据载体(下文命名为ListData_IconFont
  2. 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_IconFontConstruct事件中,读取数据表:

  1. 读取数据表,循环构建ListData_IconFont对象并填入数据。同时把自己 (Self) 传进去,以便后续跨蓝图通信。
  2. 将构建好的对象存入数组,并最终交由 TileViewSet List Items
  3. 记得在重建列表前先 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带的节点啊