Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Duplicating a node that originates from a PackedScene causes some Controls to break #84803

Closed
Trantarius opened this issue Nov 12, 2023 · 1 comment · Fixed by #84824
Closed
Milestone

Comments

@Trantarius
Copy link

Godot version

4.1.3.stable and v4.2.beta.custom_build [d443f12]

System information

Godot v4.1.3.stable unknown - Arch Linux #1 SMP PREEMPT_DYNAMIC Thu, 26 Oct 2023 00:52:20 +0000 - Wayland - Vulkan (Forward+) - dedicated AMD Radeon RX 6700 XT (RADV NAVI22) () - AMD Ryzen 7 3700X 8-Core Processor (16 Threads)

Issue description

When a duplicating a node (via Node.duplicate()) that is the root of a sub-scene, control nodes that create internal child nodes will have multiple child nodes in the duplicated version.

The expected result is to produce a node tree with only one set of internal nodes for those controls:

SpinBox
 ┠╴@LineEdit@21
 ┖╴@Timer@22

However, the duplicated scene has extra internal nodes:

SpinBox
 ┠╴@LineEdit@26
 ┠╴@Timer@27
 ┠╴_LineEdit_24
 ┖╴_Timer_25

In the case of spinbox, the extra lineedit is drawn on top of the original. The extra lineedit does not properly cause the value of the spinbox to change, and the up/down buttons only affect the original lineedit. The bug affects other control nodes too (like OptionButton), but I have only seen functionality impacted with SpinBox. It can be prevented by setting the node's scene_file_path to an empty string before duplicating.

Steps to reproduce

  1. create a new scene
  2. create a sub-scene by dragging a .tscn file into the node tree in the editor
  3. make a script duplicate that subscene with Node.duplicate()
  4. add the duplicate to the scene

Alternatively, the sub-scene can be created at runtime from a packed scene and then duplicated.

Minimal reproduction project

ControlDuplicateIssue.zip

The first column of controls uses a sub-scene created in the editor, and exhibits the bug in the second row.

The second column uses a local version of the sub-scene (made via right click -> make local in the editor) and does not exhibit the bug.

The third column creates and adds a sub-scene from a script, and exhibits the bug in the second row.

The fourth column is like the third, but circumvents the bug by first setting the node's scene_file_path to an empty string before duplicating.

@Rindbee
Copy link
Contributor

Rindbee commented Nov 13, 2023

Internal nodes are mistakenly treated as hidden_root and then duplicated again.

godot/scene/main/node.cpp

Lines 2502 to 2505 in 6415006

if (!instance_roots.has(descendant->get_owner())) {
if (descendant->get_parent() && descendant->get_parent() != this && descendant->data.owner != descendant->get_parent()) {
hidden_roots.push_back(descendant);
}

godot/scene/main/node.cpp

Lines 2600 to 2607 in 6415006

for (const Node *&E : hidden_roots) {
Node *parent = node->get_node(get_path_to(E->data.parent));
if (!parent) {
memdelete(node);
return nullptr;
}
Node *dup = E->_duplicate(p_flags, r_duplimap);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants