From c3a61d531fe041e939ecc109cea7a20e44876567 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E9=A3=8E=E9=9D=92=E5=B1=B1?= Date: Tue, 27 Jan 2026 10:18:48 +0800 Subject: [PATCH] Fix the issue with `ViewportTexture` assignment For properties like `ViewportTexture.viewport_path` that enable `PROPERTY_USAGE_NODE_PATH_FROM_SCENE_ROOT`. The case of enabling **Editable Children** to edit nodes in a child scene seems to have been overlooked before. The `EditorPropertyResource` also missed the **Editable Children** case when handling `ViewportTexture`. --- editor/inspector/editor_properties.cpp | 76 +++++++++++++++++++++++--- editor/inspector/editor_properties.h | 1 + 2 files changed, 69 insertions(+), 8 deletions(-) diff --git a/editor/inspector/editor_properties.cpp b/editor/inspector/editor_properties.cpp index 1cd5b83290..7b8830717e 100644 --- a/editor/inspector/editor_properties.cpp +++ b/editor/inspector/editor_properties.cpp @@ -3242,15 +3242,29 @@ Node *EditorPropertyNodePath::get_base_node() { } } } - if (use_path_from_scene_root) { - if (get_edited_object()->has_method("get_root_path")) { - base_node = Object::cast_to(get_edited_object()->call("get_root_path")); - } else { - base_node = get_tree()->get_edited_scene_root(); - } + + if (!use_path_from_scene_root) { + return base_node; } - return base_node; + if (get_edited_object()->has_method("get_root_path")) { + return Object::cast_to(get_edited_object()->call("get_root_path")); + } + + if (!base_node) { + return nullptr; // Editing external resources. + } + + if (base_node->is_instance()) { + return base_node; // Known scene root. + } + + base_node = base_node->get_owner(); + if (base_node) { + return base_node; // Node in known scene. + } + + return get_tree()->get_edited_scene_root(); // Treat as a node in the main scene. } EditorPropertyNodePath::EditorPropertyNodePath() { @@ -3354,6 +3368,17 @@ void EditorPropertyResource::_resource_changed(const Ref &p_resource) } } + if (p_resource.is_valid() && p_resource->is_local_to_scene()) { + // Attempting to configure the local scene. + Node *local_scene = _get_base_node(); + if (local_scene) { + HashMap, Ref> remap; + p_resource->configure_for_local_scene(local_scene, remap); + } else { + WARN_PRINT("You are attempting to assign a local-to-scene resource outside the scene."); + } + } + // The bool is_script applies only to an object's main script. // Changing the value of Script-type exported variables of the main script should not trigger saving/reloading properties. bool is_script = false; @@ -3471,6 +3496,39 @@ bool EditorPropertyResource::_should_stop_editing() const { return !resource_picker->is_toggle_pressed(); } +Node *EditorPropertyResource::_get_base_node() { + Node *base_node = Object::cast_to(get_edited_object()); + + if (!base_node) { + base_node = Object::cast_to(InspectorDock::get_inspector_singleton()->get_edited_object()); + } + + if (!base_node) { + // Try a base node within history. + if (EditorNode::get_singleton()->get_editor_selection_history()->get_path_size() > 0) { + Object *base = ObjectDB::get_instance(EditorNode::get_singleton()->get_editor_selection_history()->get_path_object(0)); + if (base) { + base_node = Object::cast_to(base); + } + } + } + + if (!base_node) { + return nullptr; // Editing external resources. + } + + if (!base_node->get_scene_file_path().is_empty()) { + return base_node; // Known scene root. + } + + base_node = base_node->get_owner(); + if (base_node) { + return base_node; // Node in known scene. + } + + return get_tree()->get_edited_scene_root(); // Treat as a node in the main scene. +} + void EditorPropertyResource::_viewport_selected(const NodePath &p_path) { Node *to_node = get_node(p_path); if (!Object::cast_to(to_node)) { @@ -3481,7 +3539,9 @@ void EditorPropertyResource::_viewport_selected(const NodePath &p_path) { Ref vt = get_edited_property_value(); ERR_FAIL_COND(vt.is_null()); - vt->set_viewport_path_in_scene(get_tree()->get_edited_scene_root()->get_path_to(to_node)); + Node *local_scene = _get_base_node(); + ERR_FAIL_NULL(local_scene); + vt->set_viewport_path_in_scene(local_scene->get_path_to(to_node)); emit_changed(get_edited_property(), vt); update_property(); diff --git a/editor/inspector/editor_properties.h b/editor/inspector/editor_properties.h index e8b1b2b493..6cc35a37e5 100644 --- a/editor/inspector/editor_properties.h +++ b/editor/inspector/editor_properties.h @@ -746,6 +746,7 @@ class EditorPropertyResource : public EditorProperty { void _resource_selected(const Ref &p_resource, bool p_inspect); void _resource_changed(const Ref &p_resource); + Node *_get_base_node(); void _viewport_selected(const NodePath &p_path); void _sub_inspector_property_keyed(const String &p_property, const Variant &p_value, bool p_advance);