From fc0cbb3171e184825f5c425030774c304e62c492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A3=8E=E9=9D=92=E5=B1=B1?= Date: Sun, 1 Jun 2025 16:13:37 +0800 Subject: [PATCH] Fix the extra arguments of type `NodePath` in the connection dialog do not work Make the node path relative to the target node instead of the source node. Currently, a proxy object is used in the connection dialog to edit bound arguments. In this case, the `EditorPropertyNodePath` will get the node path relative to the source object in the connection (i.e. the object the InspectorDock is editing). This path is not available in scripts (i.e. the target object in the connection). --- editor/inspector/editor_properties.cpp | 5 +++++ editor/scene/connections_dialog.cpp | 30 ++++++++++++++++++++++++++ 2 files changed, 35 insertions(+) diff --git a/editor/inspector/editor_properties.cpp b/editor/inspector/editor_properties.cpp index ebf3e289448..50c996b2dd4 100644 --- a/editor/inspector/editor_properties.cpp +++ b/editor/inspector/editor_properties.cpp @@ -3069,6 +3069,11 @@ void EditorPropertyNodePath::_notification(int p_what) { Node *EditorPropertyNodePath::get_base_node() { Node *base_node = Object::cast_to(get_edited_object()); + // For proxy objects, specifies the node to which the path is relative. + if (!base_node && get_edited_object()->has_meta("__base_node_relative")) { + base_node = Object::cast_to(get_edited_object()->get_meta("__base_node_relative")); + } + if (!base_node) { base_node = Object::cast_to(InspectorDock::get_inspector_singleton()->get_edited_object()); } diff --git a/editor/scene/connections_dialog.cpp b/editor/scene/connections_dialog.cpp index f5b0f8b49a0..c39da08b05d 100644 --- a/editor/scene/connections_dialog.cpp +++ b/editor/scene/connections_dialog.cpp @@ -113,6 +113,33 @@ public: } } + void update_base_node_relative(Node *p_node) { + Node *old_base = nullptr; + if (has_meta("__base_node_relative")) { + old_base = Object::cast_to(get_meta("__base_node_relative")); + } + + if (old_base == p_node) { + return; + } + // The cdbinds is a proxy object, so we want the node path to be relative to the target node. + set_meta("__base_node_relative", p_node); + + if (!old_base) { + return; + } + + // Update existing outdated node paths. + for (int i = 0; i < params.size(); i++) { + if (params[i].get_type() != Variant::NODE_PATH) { + continue; + } + StringName property_name = "bind/argument_" + itos(i + 1); + Node *n = old_base->get_node(get(property_name)); + set(property_name, p_node ? p_node->get_path_to(n) : NodePath()); + } + } + void notify_changed() { notify_property_list_changed(); } @@ -176,6 +203,9 @@ void ConnectDialog::_tree_node_selected() { if (!edit_mode) { set_dst_method(generate_method_callback_name(source, signal, current)); } + + cdbinds->update_base_node_relative(current); + _update_method_tree(); _update_warning_label(); _update_ok_enabled();