The problem with .duplicate in the GUI

Godot Version

Godot 4.4.1

Question

Hello, I have a problem when I create a new display in the GUI using .duplicate, then I don’t copy everything, please help.

Code (function):

func add_unit_display(unit: CharacterBody3D) -> void:
	var new_element = $BG.duplicate(true) 
	add_child(new_element)
	new_element.get_child(0).editor_description = str(unit)
	new_element.top_level = true
	new_element.visible = true
	army_elements.append(new_element)
	unit.reparent($ARMS)

Error:

E 0:00:04:216   army.gd:81 @ add_unit_display(): Node not found: "Many/ScrollContainer/VBoxContainer/@Button@3" (relative to "BG").
  <Error C++>  Method/function failed. Returning: nullptr
  <Source code C++>scene/main/node.cpp:1877 @ get_node()
  <Stack tracing>army.gd:81 @ add_unit_display()
                army.gd:70 @ update_army_display()
                army.gd:47 @ _process()

What do you see if you call new_element.print_tree_pretty()?

1 Like

@ColorRect@5
┠╴Name
┠╴One
┃ ┠╴IconPer
┃ ┠╴Vibor
┃ ┖╴Stat
┠╴Many
┃ ┠╴ScrollContainer
┃ ┃ ┠╴VBoxContainer
┃ ┃ ┃ ┠╴Varm
┃ ┃ ┃ ┠╴ArmName
┃ ┃ ┃ ┠╴_Button_3
┃ ┃ ┃ ┖╴_Button_4
┃ ┃ ┠╴_h_scroll
┃ ┃ ┖╴_v_scroll
┃ ┖╴Stat
┖╴Clouse

The error is complaining about @Button@3, but you have _Button_3. It looks to me like the names are getting mangled.

1 Like

Do you know how to fix it? :pleading_face::pleading_face::pleading_face:

I don’t know if there’s a more systematic way, but there’s always brute force:

func add_unit_display(unit: CharacterBody3D) -> void:
	var new_element = $BG.duplicate(true) 
    new_element.get_node("ScrollContainer/VBoxContainer/_Button_3").name = "Button3"
    new_element.get_node("ScrollContainer/VBoxContainer/_Button_4").name = "Button4"
    [...]

I won’t be able to test this method today, but it looks interesting. I’ll try it tomorrow. Thank

Hello, I tried this method after the “var new_element = $BG.duplicate(true)” line. Although “new_element.print_tree_pretty()” shows what it’s supposed to show, the error still exists, and it’s specifically in the line with “var new_element = $BG.duplicate(true)”.

That implies _Button_3 is not a valid instance somehow. Is the thing you’re duplicating maybe not fully created yet? As in, some of its children are not yet created?

Idk. I’ll try to do something about it, but I don’t have any ideas.

Maybe before calling duplicate, recursively walk over the thing you’re duplicating and call is_valid_instance() on all the children? It would only be a debug/testing thing, but if any of those calls came back false it would be diagnostic.