自定义 VisualScript 节点

警告

Godot 4.0 将会把 VisualScript 从核心中完全移除。因此,不推荐在新的 Godot 项目中使用可视化脚本。后续的 Godot 4.x 版本可能会将 VisualScript 重新实现为扩展。

Godot 3.x 仍会支持 VisualScript,我们建议你先试一试 GDScript,尤其是你想要把项目移植到 Godot 4 的话。

自定义节点可以用 GDScript 定义,并在 VisualScript 中使用。这对分流复杂代码到 GDScript 并反复使用尤为有用。

创建自定义节点

新建一个继承 VisualScriptCustomNode 类的脚本, 并在代码顶端添加 tool 关键字. tool 能让脚本在编辑器中运行.

你可以实现一些能够设置自定义节点参数的函数 (继承自 VisualScriptCustomNode 的虚函数). 只需要实现那些有必要的函数, 假如你知道 _has_input_sequence_port 一定会返回 false, 则没有必要实现它.

自定义节点最重要的部分就是 _step 函数. 你需要在这个函数中定义节点的逻辑.

inputs 参数传入可视化节点输入端口的值.

outputs 参数是一个数组, 数组下标代表了输出接口的 ID. 可以通过修改数组元素来修改输出接口的值.

start_mode 可以用来检查是否是首次调用 _step 函数.

working_mem 每次调用 _step 时不变(引用同一个数组). 可以用它来储存信息.

若你想抛出一个错误, 例如输入类型不正确时, 可以将错误信息返回为字符串. 若一切安好, 则返回下一个将被调用的序列接口的 ID. 如果你的自定义节点没有需要调用的接口, 则返回 0.

示例:

tool
extends VisualScriptCustomNode

# The name of the custom node as it appears in the search.
func _get_caption():
    return "Get Input Direction 2D"

func _get_category():
    return "Input"

# The text displayed after the input port / sequence arrow.
func _get_text():
    return ""

func _get_input_value_port_count():
    return 0

# The types of the inputs per index starting from 0.
func _get_input_value_port_type(idx):
    return TYPE_OBJECT

func _get_output_value_port_count():
    return 1

# The types of outputs per index starting from 0.
func _get_output_value_port_type(idx):
    return TYPE_VECTOR2

# The text displayed before each output node per index.
func _get_output_value_port_name(idx):
    return "Direction"

func _has_input_sequence_port():
    return true

# The number of output sequence ports to use
# (has to be at least one if you have an input sequence port).
func _get_output_sequence_port_count():
    return 1

func _step(inputs, outputs, start_mode, working_mem):
    # start_mode can be checked to see if it is the first time _step is called.
    # This is useful if you only want to do an operation once.

    # working_memory is persistent between _step calls.

    # The inputs array contains the value of the input ports.

    var x = int(Input.is_action_pressed("ui_right")) - int(Input.is_action_pressed("ui_left"))
    var y = int(Input.is_action_pressed("ui_down")) - int(Input.is_action_pressed("ui_up"))

    # The outputs array is used to set the data of the output ports.

    outputs[0] = Vector2(x, y)

    # Return the error string if an error occurred, else the id of the next sequence port.
    return 0

使用自定义节点

要使用你的自定义节点脚本,视图上方点击添加节点,新增一个 CustomNode,选定它,并将你的脚本拖拽进检查器的 script 属性中。

../../../_images/visual_script_custom_node_set_script.png

结果:

../../../_images/visual_script_custom_node_result.png