可脚本化工具(Scriptable Tools) 系统旨在让非C++程序员能够在虚幻编辑器中构建交互式工具。交互式工具的主要参考标准是建模模式。但是,可脚本化工具系统与建模或网格体没有直接联系。
可脚本化工具系统插件 ScriptableInteractiveTool 可将 交互式工具框架 公开给蓝图(BP),让创作者和技术美术师可以设计出作用类似于建模模式的工具。
通过创建基类的BP子类,可以将自定义用户定义的工具添加到 可脚本化工具编辑器模式(Scriptable Tools Editor Mode) 。这些可脚本化工具可以与几何体脚本处理搭配使用,以实现复杂的建模和资产编辑工作流程。你还可以将这些工具用于与建模或几何体无关的更简单的功能。
可脚本化工具有何用途?
你可以使用可脚本化工具,创建一种迷你模式进行以下操作:
- 在工具设置和关闭以及在函数更新时,运行任意蓝图(BP)图表。
- 绘制基本的3D几何体(线条、点)和2D HUD几何体(投影3D位置的文本)。
- 将属性集添加到工具中,通过蓝图定义,用作工具的设置。
- 监听并响应这些属性集参数的变化。
- 创建一个或多个3D小工具,控制它们的位置并响应变换变化。
- 向用户提供反馈信息。
- 捕获并响应特定类型的鼠标交互,特别是视口内的点击和点击拖动交互,以及鼠标悬停和shift、ctrl和alt修饰键。
你可以从可脚本化工具编辑器模式访问所有可脚本化工具,其中每个工具都显示在自动管理的工具控制板中,并且激活工具的属性集在标准编辑器模式细节面板中公开。如需详细了解编辑器模式,请参阅工具和编辑器。
请查看本页面创建可脚本化工具小节中的教程,了解如何创建在关卡中生成新动态网格体球体的工具。

可脚本化工具和编辑器工具控件
编辑器工具控件(EUW)是一个非模态对话框窗口,包含通过可视化GUI编译器编译的自定义UI,你可以在其中执行任何类型的编辑器脚本处理。这是一个非常强大的工具,但作为非模态对话框,存在各种限制。
交互式工具(可脚本化工具的基础)是 模态 的,这意味着当该工具激活时,其他工具都不能激活,并且编辑器状态受到更严格的管理。例如,该工具会在保存、更改关卡或启动在编辑器中运行(PIE)之前自动关闭,并且自动保存会推迟到你退出该工具之后。这意味着很多事情用工具做要比其他方式更安全。例如,如果你在关卡中创建了临时Actor,并在工具关闭时将其销毁,那么临时Actor就不会被意外保存。
同样,作为模态状态,工具可以更有效地捕获鼠标。
在UI方面,可脚本化工具比EUW更加结构化。你可以将属性集定义为具有公共变量的单独BP对象。然后,这些公共变量将显示在标准的细节面板中。从某些方面来看,这比EUW简单得多,当然了,这种简单也伴随着很多限制。目前还没有办法为可脚本化工具编译自定义UI。
从技术上讲,可脚本化工具在运行时也可用,但必须设置一些额外的架构才能在UE项目中加以使用。
UInteractiveScriptabletool
UInteractiveScriptabletool 是所有可脚本化工具的基类。但是,为了编译编辑器工具,你很可能要子类化 EditorInteractiveScriptabletool ,否则你将无法访问仅限编辑器的BP功能。
可脚本化工具设置
基类将公开各种设置,主要用于可脚本化工具编辑器模式UI,也可控制工具行为。

节点 | 说明 |
---|---|
工具名称(Tool Name) | 工具简称。这是当前在工具图标下显示的内容。 |
长名称(Long Name) | 显示在其他地方,例如工具完成按钮旁边。 |
类别(Category) | 确定工具将放置在哪个工具控制板分段中。 |
提示文本(Tooltip) | 图标悬停文本,可以提供有关该工具含义的信息。 |
在编辑器中可见(Visible in Editor) | 确定此工具类是否在模式的UI中显示。这对于隐藏正在开发的工具或计划子类化的工具BP基础案例很有用。 |
关闭类型(Shutdown Type) | 确定该工具是 接受/取消 式工具,还是 完成 式工具。这会影响工具的功能,后面会进一步讨论。 |
可脚本化工具事件
可脚本化工具类提供了一组标准事件,以便工具在不同时间执行不同的操作。每个工具类都有五个标准事件,并且在下述 基础工具(Base tools) 中提供了各种附加函数。
-
脚本设置事件(Event On Script Setup) :在工具启动时运行一次。通常发生在你添加属性集、创建预览对象等活动的时候。
-
脚本函数更新事件(Event On Script Tick) :每次编辑器函数更新时运行,就像其他函数更新一样。
-
脚本关闭事件(Event On Script Shutdown) :在工具关闭时运行。例如,当用户明确关闭该工具时,该模式强制其关闭,或者该工具自行关闭
-
脚本绘制HUD事件(Event On Script Draw HUD) :每帧运行,并且工具可以从 HUD API 对象绘制2D HUD。如需更多信息,请参阅下面的小节。
-
脚本渲染事件(Event On Script Render) :每帧运行,并允许工具绘制简单的3D几何体,如线条和点。

工具渲染
要在工具中提供视觉反馈是很常见的需求。例如,这总是可以通过生成临时Actor来完成 (例如,使用由几何体脚本程序化生成的网格体生成临时动态网格体Actor,这是一种非常简单的实现方法)。然而,通常线条或文本标签会更有效。
工具通过提供具有一组 Ufunction
节点的API对象来支持这种渲染。2D绘制HUD和3D渲染事件分别通过 DrawHUDAPI
和 RenderAPI
对象调用。该工具在内部创建并管理这些API对象。你只能通过这些事件访问API对象,因为它们依赖工具提供的每帧临时状态信息。
BP中还有一个标准的调试绘制(Debug Draw)函数库。这些也可以用作DrawHUD和Render函数的替代方案,并且可以随时调用。但是,这些函数仅用于开发,工具Render API最终将提供更多功能。_
小工具
可脚本化工具基类的另一个功能是能够创建多个3D变换小工具。这不是标准编辑器小工具,而是建模模式的小工具。系统提供了一组函数来创建和管理小工具,以及一个事件来响应小工具变化。
小工具对象不会直接公开给蓝图。而是使用字符串 标识符 生成小工具,并通过该标识符运行各种小工具函数和事件。

节点 | 说明 |
---|---|
CreateTRSGizmo | 使用给定的 标识符 和 小工具选项 创建TRS(平移、旋转和缩放)小工具。如需更多信息,请参阅下文有关选项的信息。 |
DestoryTRSGizmo | 按名称销毁现有小工具。在工具上下文中创建的所有小工具都会在工具关闭时销毁。 |
Get Gizmo Transform | 按名称获取小工具的当前变换。 |
Set Gizmo Transform | 按名称更新小工具的当前变换。 |
Set Gizmo Visible | 按名称隐藏或显示小工具。 |
Event On Gizmo Transform Changed | 在激活的小工具发生变换时触发。使用标识符来辨别哪个小工具被修改。 |
基本TRS小工具结合了所有轴的平移、旋转和缩放元素。但是,你可以通过自定义 小工具选项 ,为特定任务创建更简单的小工具。例如,通过禁用其他小工具子元素,仅启用XY平面中的平移和旋转。

工具消息
标准可脚本化工具BP API提供了用于向用户发送消息的各种函数。
-
显示用户帮助消息(Display User Help Message) 可更新编辑器UI底部的帮助字符串。
-
显示用户警告消息(Display User Warning Message) 可更新工具设置面板中的字符串。
- 清除用户消息(Clear User Messages) 可用于清除当前的帮助或警告消息。
- 添加日志消息(Add Log Message) 当前将消息打印到编辑器的日志中。
上述消息是FText字符串,因此可本地化。当前只能显示单个警告,将来可能会有所改进。_
杂项
可脚本化工具始终在当前世界的上下文中运行。例如,在关卡编辑器中,将是标准关卡世界。你可以使用 Get Tool World 函数在工具上下文中访问此世界。
工具关闭
退出可脚本化工具的标准流程是单击UI中显示的接受(Accept)、取消(Cancel)或完成(Complete)按钮。但是,也可以通过 Request tool Shutdown 函数明确关闭可脚本化工具,工具也可以自行调用该函数。此函数采用仅与接受/取消式工具相关的 bAccept 标记,以及可选的用户弹出消息。
工具属性集
可脚本化工具可以通过 属性集 UObjects向用户公开UI控件,这些控件显示在标准细节面板中。目前无法在蓝图中自定义此UI,因此仅标准属性设置(类似于可以对Actor BP中的参数执行的操作)可用。
要创建 属性集 ,首先要创建 ScriptableInteractivetoolPropertySet 类型的BP子类,如下所示。

然后,你可以打开属性集子类BP进行编辑,并添加公共成员变量。下面添加了布尔、整型和枚举类型。

要在特定的可脚本化工具中使用属性集,请使用函数 Add Property Set of Type。该函数一般用于 脚本设置事件(Event On Script Setup),但也可以在任何时候使用。你必须为 属性集类型(Property Set Type) 参数选择正确的类类型——即选择你上面创建的BP子类的类型名称。此外,你必须为每个不同的属性集设置唯一的 标识符 (你可以在单个工具中组合多个属性集)。最后,由于你稍后可能需要访问此属性集对象,因此建议将 添加类型属性集(Add Property Set Of Type) 的输出转换为你的BP子类类型,并将其存储在本地变量中。

现在,当用户创建可脚本化工具的实例时,属性集的公共成员变量将显示在左侧的 可脚本化工具(Scriptable Tools) 设置面板中,位于工具控制板旁边。

可脚本化工具类具有各种用于处理属性集的辅助函数。你可以使用 按名称删除属性集(Remove Property Set by Name) 来删除属性集,但请注意,大多数情况下没有必要这样做。如果你只是想根据某些标准或其他参数变化隐藏或显示属性集,请使用 按名称将属性集设置为可见(Set Property Set Visible by Name) 。
此外,你可以在工具关闭时使用 保存属性集设置(Save Property Set Settings) 存储属性集的当前值,而 恢复属性集设置(Restore Property Set Settings) 可以恢复在设置工具时保存的值。默认情况下,在任何工具中使用属性集类都会恢复相同的值。但是,可以提供可选的 保存键(Save Key) 来在不同的工具中或者甚至在同一个工具中保存或恢复不同的值。

属性监视器
属性集的最常见用途可能就是响应属性值的变化。这可能较难处理,唯一完全可靠的解决方案是轮询更新函数中的值变化。但是,由于这是一种常见模式,因此可脚本化工具提供了工具属性监视器函数,可以自动执行这种轮询。
你可以在可脚本化工具中使用下面的函数监视属性集特定属性的变化,并在该值被修改时调用事件。
在BP中,目前无法从变量引用中自动检测UProperty类型,因此你必须:
- 确保使用与属性集中的公共变量类型匹配的函数
- 传递正确的 属性名称 (属性集中公共变量的名称)。
如果类型不是简单类型(Int、Float、Bool、String、FName、Enum或Object Property),则可以使用通用的 监视属性(Watch Property) 版本,但其回调事件更受限制。

下面是 Watch Enum Property 函数的使用示例。这是简单类型中最复杂的,因为枚举类型未知。将传递给回调事件的 新值(New Value) 参数是uint8,并且必须明确转换为正确的UEnum类型(在本例中为 EGeometryScriptAxis )。目前无法在此进行错误检查,该函数将转换为枚举类型。

最后,对于更复杂的参数(例如,像FVector成员变量一样的嵌套UStruct),可以使用 Watch Property 函数。该函数几乎可以检测任何UProperty变量的变化,但是回调事件不会像其他字段一样接收 新值(New Value) 参数。但是,如果你在工具中为属性集创建了成员变量,则可以直接在事件中获取属性值。这种类型的监视器的计算开销也更高,因此只应在必要时使用。

基础工具
基础工具是可脚本化交互式工具框架的C++子类,提供额外的内置功能来处理常见情况和/或公开其他功能,如输入设备处理和捕获。
可脚本化单击工具
鼠标点击支持:
-
TestIfHitByClick:必须返回有效的 FInputRayHit,指示命中深度,以捕获鼠标点击。
-
OnHitByClick:按下和释放鼠标后发生点击时调用。
悬停支持:
-
OnHoverHitTest:必须返回有效的 FInputRayHit,指示命中深度,以捕获悬停。
-
OnHoverBegin:传递 OnHoverHitTest 后,当悬停序列开始时调用。
-
OnHoverUpdate:每次光标在悬停状态下移动时调用。
-
OnHoverEnd:悬停结束时调用。

可脚本化点击拖动工具
鼠标拖动支持:
-
TestIfCanBeginClickDrag:必须返回有效的FInputRayHit,指示命中深度,以开始拖动序列。
-
OnDragBegin:传递TestIfCanBeginClickDrag后,在拖动序列开始时调用。
-
OnDragUpdatePosition:在拖动序列期间,当光标移动时调用。
-
OnDragEnd:当拖动序列由于鼠标释放而终止时调用。
-
OnDragSequenceCancelled:当拖动序列由于各种原因(例如退出键和窗口失焦)终止时调用。
悬停支持:
-
OnHoverHitTest:必须返回有效的FInputRayHit,指示命中深度,以捕获悬停。
-
OnHoverBegin:传递OnHoverHitTest后,当悬停序列开始时调用。
-
OnHoverUpdate:每次光标在悬停状态下移动时调用。
-
OnHoverEnd:悬停结束时调用。

启用仅限编辑器插件
配置 TargetAllowList
分段,只在 uproject
和 uplugin
文件中包含 Editor
,这些文件仅需ScriptabletoolsFramework或ScriptabletoolsEditorMode即可在编辑器中使用:
{
"Name": "ScriptabletoolsEditorMode",
"Enabled": true,
"TargetAllowList": [
"Editor"
]
},
创建可脚本化工具
本指南向你介绍了如何创建新的工具蓝图,该蓝图可在你点击鼠标时,在关卡中生成新的动态网格体球体,并在工具的UI中公开半径属性。
启用插件
若要使用可脚本化工具编辑器模式,需要启用相关插件。
要启用该插件或验证插件是否已启用,请按照以下步骤操作:
- 在 菜单栏 中,选择 编辑(Edit) > 插件(Plugins) 。
-
在搜索栏中输入"scriptable tools"。
- 启用 可脚本化工具编辑器模式(Scriptable Tools Editor Mode) 插件,并在弹出的对话框中选择 是(Yes) 。你无需启用可脚本化工具框架模块,编辑器模式会自动将其包含在内。
- 以下步骤中的某些函数还需要 几何体脚本处理(Geometry Scripting) 插件,因此如果你还没有启用该插件,请启用。
- 重新启动编辑器,然后在 选择模式(Selection Mode) 下拉菜单中切换到新模式,即 可脚本化工具(Scriptable Tools) 模式。
-
你会看到类似于下面的UI,左侧有一个空的工具控制板。
核心设置
-
在 内容浏览器(Content Browser) 中点击右键,在弹出窗口中选择 编辑器工具(Editor Utilities) 子菜单,并创建新的 编辑器工具蓝图(Editor Utility Blueprint)。在搜索框中输入"Scriptable",然后选择 EditorScriptableSingleClicktool。
不一定需要使用"编辑器工具蓝图(Editor Utility Blueprint)",你也可以创建常规的 蓝图类(Blueprint Class) 。但是,如果你正在创建编辑器工具,并且使用蓝图类而非编辑器工具蓝图,那么你将无法访问编辑器子系统和各种其他仅限编辑器的功能(即使是在EditorScriptabletool内部)。
-
将新的BP资产命名为
tool_MakeSphere
,然后 点击右键 并选择 编辑(Edit),或 双击 该资产,以打开蓝图。在BP编辑器右侧的 细节(Details) 面板中,你可以为该工具命名,本示例中使用的是"球体(Sphere)"。同时用字符串填写 类别(Category) 名称。 -
编译(Compile) (Ctrl + Alt)并 保存(Save) (Ctrl + S)。切换回可脚本化工具模式。球体(Sphere) 工具现在应显示在工具控制板中具有相应 类别 名称的分段中。
-
现在你可以运行球体工具,当然它不会执行任何操作,但你可以启动该工具。使用视口底部中央的 完成(Complete) 按钮退出该工具。
-
返回BP编辑器。在左侧面板中,将鼠标悬停在 函数(Functions) 分段的末尾。将出现 重载(Override) 下拉菜单。选择 Test If Hit By Click,创建鼠标点击测试新事件。下拉列表中的函数是你可以实现的可用工具API函数。
-
按如下所示连接函数。
-
为 On Hit By Click 事件添加第二个 重载(Override)。
-
右键点击 Event On Hit By Click 中的 Click Pos 引脚,并选择 拆分结构体引脚(Split Struct Pin)。然后连接Click事件,如下所示。此处本质上是,你重复与命中测试事件相同的线路追踪,然后在命中时生成 动态网格体Actor (这里的节点最初是"Spawn actor from Class",然后一旦你在下拉菜单中选择动态网格体Actor,名称就会更改),然后使用几何脚本处理将该Actor中的网格体设置为球体。
右键点击BP节点中的某些引脚,可以使用 Split Struct Pin 选项来简化图表。
-
编译并返回主视口,然后运行球体工具。在视口中点击,新球体应被置于点击位置。
添加半径属性
现在,你已经创建好了基础工具。要扩展其功能,你可以为球体添加半径设置。
-
回到内容浏览器,点击右键,创建新的 蓝图类(Blueprint Class),在搜索框中输入"propertyset",然后选择 ScriptableInteractivetoolPropertySet。为新的BP资产命名(我使用的是"MakeSphere_Settings"),然后打开资产进行编辑。
-
在左侧的 变量(Variables) 分段,点击圆圈内的+号,添加新变量。将其命名为 Radius,将类型更改为 浮点(Float),并通过点击眼睛图标将其设置为 公开(Public)(如果不将变量设置为公开,则变量不会出现在细节面板中)。编译(Compile) Ctrl + Alt)并 保存(Save)(Ctrl + S)。
-
在右侧面板中,找到 滑块范围(Slider Range) 字段,将其设置为值10和200,然后将 默认值(Default Value) 设置为50。再次 编译(Compile) 。
-
现在,返回工具蓝图并为 On Script Setup 函数添加 重载(Override)。
-
在 脚本设置事件(Event On Script Setup) 中,调用 Add Property Set Of Type 节点,并在类型下拉菜单中选择你的属性集BP类(与你上面使用的名称相同,MakeSphere_Settings)。
-
为属性集创建变量,这将简化后面的事项。添加 Cast To
节点,其中 是你的BP设置类名称(例如,MakeSphere_Settings)。 -
右键点击 As Make Sphere Settings 引脚,并选择 提升为变量(Promote to Variable)。这将自动添加新变量。将变量重命名为"Settings"。
-
返回 On Hit By Click 事件的图表,将 Settings 变量中的公开 半径(Radius) 字段连接到 Append Sphere Box 节点的 半径(Radius) 引脚,然后进行 编译(Compile)。
-
返回视口,并再次运行 球体(Sphere) 工具。现在,在细节面板中,你会看到 半径(Radius) 字段的滑块。如果你更改此值,所放置球体的大小将发生改变。
你已创建具有自定义设置的工具,并在蓝图中处理鼠标点击。