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

📅 2026/7/9 14:11:28
【UE】在UMG中引入Web矢量图标库,彻底告别找图切图。再做一个可视化检索工具
在开发 UE UI 时我们经常需要海量的高清图标。与其到处找图、切图、做PaperSprite优化。不如直接引入前端 Web 开发中常用的矢量图标库。这类图标不仅资源丰富而且打包成字体后体积极小、无限放大不失真。本文将演示如何将开源 SVG 图标库转换为 UE 字体资产并进阶制作一个编辑器控件实现图标的可视化检索与一键复制。一、 准备图标1. 找到图标库首先找到一个高质量的开源图标库。这种图标在 HTML/CSS 中有大量应用资源极多。[一个很华丽的图标库][一个很商业的图标库]这里应该列举一些开源库但是我太懒了有空整理2. 下载 SVG 库以下教程以开源免费的图标库Reicon为例。可以看到它有Outline 轮廓和Filled 填充两种样式非常适合作为教程案例无论选择如何找到并下载打包的 SVG 格式解压文件后可以看到官方已经按样式分好了两个文件夹里面包含的就是独立的 SVG 格式图标二、 将 SVG 转换为字体这里我们使用主流的在线SVG Editor工具将这堆图片打包成字体文件。前往Icomoon1. 新建项目在左上角New (新建)一个项目并点击Load (载入)2. 导入 SVG在Import 导入中点击Select 选择按钮。找到本地目录。注意一次只导入一个样式我们先导入 Outline 的CtrlA全选所有 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;letrowIndex1;for(const[hexCode,iconName]ofObject.entries(names)){// 把编码转成 Unicode 字符letactualCharString.fromCharCode(hexCode);csvContent${rowIndex},${iconName},${actualChar}\n;rowIndex;}constblobnewBlob([csvContent],{type:text/csv;charsetutf-8;});constlinkdocument.createElement(a);link.hrefURL.createObjectURL(blob);link.downloadReiconData.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_IconFontEntry Widget视觉表现按钮下文命名为ListButton_IconFont2.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) 传进去以便后续跨蓝图通信。将构建好的对象存入数组并最终交由 TileViewSet 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带的节点啊