diff --git a/doc/classes/VisualShaderNode.xml b/doc/classes/VisualShaderNode.xml
index 6b188a607d7..5d147bd542b 100644
--- a/doc/classes/VisualShaderNode.xml
+++ b/doc/classes/VisualShaderNode.xml
@@ -16,6 +16,13 @@
Clears the default input ports value.
+
+
+
+
+ Returns the input port which should be connected by default when this node is created as a result of dragging a connection from an existing node to the empty space on the graph.
+
+
diff --git a/doc/classes/VisualShaderNodeCustom.xml b/doc/classes/VisualShaderNodeCustom.xml
index 480f7dfe0e8..8a90d5dd0f6 100644
--- a/doc/classes/VisualShaderNodeCustom.xml
+++ b/doc/classes/VisualShaderNodeCustom.xml
@@ -37,6 +37,14 @@
Defining this method is [b]required[/b].
+
+
+
+
+ Override this method to define the input port which should be connected by default when this node is created as a result of dragging a connection from an existing node to the empty space on the graph.
+ Defining this method is [b]optional[/b]. If not overridden, the connection will be created to the first valid port.
+
+
diff --git a/editor/plugins/visual_shader_editor_plugin.cpp b/editor/plugins/visual_shader_editor_plugin.cpp
index bd30c3b6b71..f180f72cdc6 100644
--- a/editor/plugins/visual_shader_editor_plugin.cpp
+++ b/editor/plugins/visual_shader_editor_plugin.cpp
@@ -3083,6 +3083,9 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector &p_ops, Stri
if (!is_native) {
vsnode->set_script(add_options[p_idx].script);
}
+ VisualShaderNodeCustom *custom_node = Object::cast_to(vsn);
+ ERR_FAIL_COND(!custom_node);
+ custom_node->update_ports();
}
bool is_texture2d = (Object::cast_to(vsnode.ptr()) != nullptr);
@@ -3211,16 +3214,26 @@ void VisualShaderEditor::_add_node(int p_idx, const Vector &p_ops, Stri
undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot);
undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot);
} else {
- // Attempting to connect to the first correct port.
+ int _to_slot = -1;
+
+ // Attempting to connect to the default input port or to the first correct port (if it's not found).
for (int i = 0; i < vsnode->get_input_port_count(); i++) {
if (visual_shader->is_port_types_compatible(output_port_type, vsnode->get_input_port_type(i))) {
- undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, i);
- undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, i);
- undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, i);
- undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, i);
- break;
+ if (i == vsnode->get_default_input_port(output_port_type)) {
+ _to_slot = i;
+ break;
+ } else if (_to_slot == -1) {
+ _to_slot = i;
+ }
}
}
+
+ if (_to_slot >= 0) {
+ undo_redo->add_undo_method(visual_shader.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot);
+ undo_redo->add_do_method(visual_shader.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot);
+ undo_redo->add_undo_method(graph_plugin.ptr(), "disconnect_nodes", type, from_node, from_slot, _to_node, _to_slot);
+ undo_redo->add_do_method(graph_plugin.ptr(), "connect_nodes", type, from_node, from_slot, _to_node, _to_slot);
+ }
}
if (output_port_type == VisualShaderNode::PORT_TYPE_SAMPLER) {
diff --git a/scene/resources/visual_shader.cpp b/scene/resources/visual_shader.cpp
index 8d034d3458d..7f1c322c8fc 100644
--- a/scene/resources/visual_shader.cpp
+++ b/scene/resources/visual_shader.cpp
@@ -46,6 +46,10 @@ bool VisualShaderNode::is_simple_decl() const {
return simple_decl;
}
+int VisualShaderNode::get_default_input_port(PortType p_type) const {
+ return 0;
+}
+
void VisualShaderNode::set_output_port_for_preview(int p_index) {
port_preview = p_index;
}
@@ -378,6 +382,8 @@ bool VisualShaderNode::is_input_port_default(int p_port, Shader::Mode p_mode) co
}
void VisualShaderNode::_bind_methods() {
+ ClassDB::bind_method(D_METHOD("get_default_input_port", "type"), &VisualShaderNode::get_default_input_port);
+
ClassDB::bind_method(D_METHOD("set_output_port_for_preview", "port"), &VisualShaderNode::set_output_port_for_preview);
ClassDB::bind_method(D_METHOD("get_output_port_for_preview"), &VisualShaderNode::get_output_port_for_preview);
@@ -481,6 +487,12 @@ String VisualShaderNodeCustom::get_input_port_name(int p_port) const {
return input_ports[p_port].name;
}
+int VisualShaderNodeCustom::get_default_input_port(PortType p_type) const {
+ int ret = 0;
+ GDVIRTUAL_CALL(_get_default_input_port, p_type, ret);
+ return ret;
+}
+
int VisualShaderNodeCustom::get_output_port_count() const {
return output_ports.size();
}
@@ -649,6 +661,7 @@ void VisualShaderNodeCustom::_bind_methods() {
GDVIRTUAL_BIND(_get_input_port_count);
GDVIRTUAL_BIND(_get_input_port_type, "port");
GDVIRTUAL_BIND(_get_input_port_name, "port");
+ GDVIRTUAL_BIND(_get_default_input_port, "type");
GDVIRTUAL_BIND(_get_output_port_count);
GDVIRTUAL_BIND(_get_output_port_type, "port");
GDVIRTUAL_BIND(_get_output_port_name, "port");
diff --git a/scene/resources/visual_shader.h b/scene/resources/visual_shader.h
index 61418b680e6..d3657eae07d 100644
--- a/scene/resources/visual_shader.h
+++ b/scene/resources/visual_shader.h
@@ -289,6 +289,7 @@ public:
virtual int get_input_port_count() const = 0;
virtual PortType get_input_port_type(int p_port) const = 0;
virtual String get_input_port_name(int p_port) const = 0;
+ virtual int get_default_input_port(PortType p_type) const;
virtual void set_input_port_default_value(int p_port, const Variant &p_value, const Variant &p_prev_value = Variant());
Variant get_input_port_default_value(int p_port) const; // if NIL (default if node does not set anything) is returned, it means no default value is wanted if disconnected, thus no input var must be supplied (empty string will be supplied)
@@ -367,6 +368,7 @@ protected:
virtual int get_input_port_count() const override;
virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
+ virtual int get_default_input_port(PortType p_type) const override;
virtual int get_output_port_count() const override;
virtual PortType get_output_port_type(int p_port) const override;
@@ -384,6 +386,7 @@ protected:
GDVIRTUAL0RC(int, _get_input_port_count)
GDVIRTUAL1RC(PortType, _get_input_port_type, int)
GDVIRTUAL1RC(String, _get_input_port_name, int)
+ GDVIRTUAL1RC(int, _get_default_input_port, PortType)
GDVIRTUAL0RC(int, _get_output_port_count)
GDVIRTUAL1RC(PortType, _get_output_port_type, int)
GDVIRTUAL1RC(String, _get_output_port_name, int)
diff --git a/scene/resources/visual_shader_nodes.cpp b/scene/resources/visual_shader_nodes.cpp
index 9eca4b91272..9d568957202 100644
--- a/scene/resources/visual_shader_nodes.cpp
+++ b/scene/resources/visual_shader_nodes.cpp
@@ -4137,6 +4137,10 @@ String VisualShaderNodeStep::get_input_port_name(int p_port) const {
return String();
}
+int VisualShaderNodeStep::get_default_input_port(PortType p_type) const {
+ return 1;
+}
+
int VisualShaderNodeStep::get_output_port_count() const {
return 1;
}
@@ -4292,6 +4296,10 @@ String VisualShaderNodeSmoothStep::get_input_port_name(int p_port) const {
return String();
}
+int VisualShaderNodeSmoothStep::get_default_input_port(PortType p_type) const {
+ return 2;
+}
+
int VisualShaderNodeSmoothStep::get_output_port_count() const {
return 1;
}
diff --git a/scene/resources/visual_shader_nodes.h b/scene/resources/visual_shader_nodes.h
index 2372bc03840..4973db0a220 100644
--- a/scene/resources/visual_shader_nodes.h
+++ b/scene/resources/visual_shader_nodes.h
@@ -1661,6 +1661,7 @@ public:
virtual int get_input_port_count() const override;
virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
+ virtual int get_default_input_port(PortType p_type) const override;
virtual int get_output_port_count() const override;
virtual PortType get_output_port_type(int p_port) const override;
@@ -1707,6 +1708,7 @@ public:
virtual int get_input_port_count() const override;
virtual PortType get_input_port_type(int p_port) const override;
virtual String get_input_port_name(int p_port) const override;
+ virtual int get_default_input_port(PortType p_type) const override;
virtual int get_output_port_count() const override;
virtual PortType get_output_port_type(int p_port) const override;