Duplicating bug (Container loading)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By display

When I duplicate a panel with a script, the click signal on the first one fires several times, and the other clones do not work. The signal is triggered 5 times, although there are 6 clones.
Here is the script for loading these panels:

var keys={"field_of_view":70,"sensitivity":.3} #example
for v in keys:
  var value= list[v]
  var new_param= param_tmp.duplicate(DUPLICATE_SCRIPTS)
  vbox.add_child(new_param)

  new_param.name= key
  new_param.label.text= key.to_camel_case()
  new_param.show()

  new_param.start(key, value)

and here is panel script



extends Panel
@onready var label=$margin/vbox/label
@onready var check=$margin/vbox/check as Button
@onready var ap:AnimationPlayer=$margin/vbox/check/ap

func start( key, value )
  change(value)
  interaction()

func interaction()
  print('interaction') #outputs several times
  check.pressed.connect(func(): #also pressed several times
    var val=!check.button_pressed
    change(val)
  )

func change(val)
  check.button_pressed=val

  if val:       ap.play('on')
  else:        ap.play('on',-1,-1,true)

I tried reproducing your issue, to no avail.
This is what I tried in Godot 4.0.3:

Node (test_duplicate.gd)
|-VBoxContainer
  |-PanelContainer (panel.gd)
    |-Button

test_duplicate.gd:

extends Node

@onready var _param_tmp = $VBoxContainer/PanelContainer
@onready var _vbox = $VBoxContainer

func _ready():
	for i in 5:
		var param = _param_tmp.duplicate(DUPLICATE_SCRIPTS)
		_vbox.add_child(param)
		param.start()

panel.gd:

extends PanelContainer

@onready var _button : Button = $Button

func start():
	_button.pressed.connect(func():
		print(str("pressed ", name))
	)

Result:
All duplicated buttons work, and “pressed” is fired once per button, printing their name. Only the first one doesn’t print because that test doesnt call start on it (I assume yours is hidden because you use it like a “template”? Usually a scene is better, to avoid cluttering the tree with template nodes and messing with duplication flags, even though it can’t reference container scene stuff, you’re setting it up by code anyways).

Maybe try to simplify your scene to isolate the problem better?

Also:

func change(val)
  check.button_pressed=val

You are calling change from within the pressed event, which… modifies button_pressed. That seems a bit weird considering that the button is already being pressed.

Zylann | 2023-07-07 10:44

Yes, thanks a lot! The problem was that they were hidden. Thank you for trying to solve the problem :slight_smile:

display | 2023-07-08 06:01