Skip to content

子图

子图节点表示当前图内部的另一个图。

子图节点的端口由内部图的暴露变量生成。

Subgraph node
父图中的子图节点。双击节点可以 dive into,进入内部图。

当用户需要进入子图时,使用 GraphEditorView。双击动作由子图节点元素处理,并请求最近的 GraphEditorView 将内部图作为新的面包屑层级打开。

Inner subgraph graph
子图内部。使用暴露变量定义子图节点端口,并通过面包屑路径返回父图。

在子图内部,不直接编辑子图节点上的端口。应该在 Blackboard 中定义变量,然后在 Inspector 中设置它们的 flow direction:

  • Input 会在面向父图的子图节点上创建输入端口。
  • Output 会在面向父图的子图节点上创建输出端口。
  • Input + Output 会创建两个方向的端口。

准确的方向映射见 Variables and Blackboard

本地子图

本地子图以内联方式存储在父图中。

SubgraphNodeModel.Kind.LOCAL 通过 UID 指向父模型 localSubGraphs 列表中的某个图。

当内部图只属于该父图时,使用本地子图。

外部子图

外部子图指向一个 IResourcePath

SubgraphNodeModel.Kind.EXTERNAL 通过 GraphModel.getReferenceResolver() 解析。

在编辑器上下文之外,resolver 可能为 null。这种情况下,子图节点会复用缓存的端口形状,让已有连线能保留下来。

从资源导入外部子图

对于基于资源的图资产,可以从 editor resource panel 把图资源拖到图画布上。

编辑器流程是:

GraphResourceProviderContainer 会保留被拖拽资源的路径,因此放下后的节点会存储稳定的外部引用,而不是复制图 NBT。

以下情况会拒绝 drop:

  • 图不允许创建子图,
  • 资源被拖放到图内容区域之外,
  • 资源路径与当前打开的根图相同,
  • 资源属于另一个图类型,并且宿主图没有通过 acceptsSubgraphGraph(...) 接受它。

导入后,该节点和其他子图节点一样使用。双击它可以编辑被引用的图。通过 dive-in view 编辑外部子图时,GraphEditorView 会通过 reference resolver 保存该层级,SubgraphRegistry 会刷新其他引用同一资源的已打开图。

变量端口

子图节点端口由内部图的变量生成:

内部变量外部子图节点
VariableKind.INPUT输入端口。
VariableKind.OUTPUT输出端口。

READ_WRITE 变量会用带后缀的端口 id 创建两个方向。

使用这个 graph hook 限制可暴露的变量方向:

java
@Override
public Set<VariableKind> getSupportedSubgraphVariableKinds() {
    return Set.of(VariableKind.INPUT, VariableKind.OUTPUT);
}

返回空集合可以禁用基于变量的子图端口。

跨类型子图

默认允许同类型本地子图。

跨类型子图需要宿主图显式允许:

java
@Override
public boolean acceptsSubgraphGraph(Graph other) {
    return other instanceof MaterialGraph;
}

这同时适用于导入的外部引用和外来本地子图。

外部保存广播

当外部图资源被保存时,SubgraphRegistry 会广播事件。

订阅者包括:

  • 需要重新定义子图节点端口的根 GraphModel 实例,
  • 可能需要重新加载或刷新已打开图 view 的编辑器监听器。

GraphEditorView 会在图加载时注册,在清理时注销。

Released under the MIT License.