button sending same signal even after reset ? [ stuck]

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

Hey there,
I spent the past 4 hours trouble shooting this issue, googling and testing.
For the life of me, I can’t get it fixed. Which is why I’m here. Crossing fingers.

In short :
I have a button that send “race” argument to open a pop up node which has one button “buy it” sending the same argument.
The button to buy it, send the argument “race” to __on_open_info_race_buy(race) where I proceed with the purchase.

That seem simple.
But the button “buy it” will always send the information from the FIRST race I clic on.
So if i open race 3. then buy it. And clic on race 2. It will still try to buy race 3.

I have tested everything.
The moment i set the signal I printed the race before and after = all good.
The variable inside the signal send 100% the right race.

But when receiving it in __on_open_info_race_buy it will always be what was clicked first.
Here is some of my code.

MAIN SCENE :

4 buttons, sending each one unique ID : 1 2 3 4 to :  _on_open_info_race(race)

In main scene script :

func _on_open_info_race(race): # BUY RACE 
var race_info = Globals._race_info(race) #race informations
#display informations
$unlock_race/frame/title.text = str(race_info[0]) #Title of the race
$unlock_race/frame/description.text = str(race_info[1]) #Description of the race
$unlock_race/frame/btn/text.text = str(race_info[2]) #Cost of the race

$unlock_race.show() #display the pop up with these infos,
$unlock_race/frame/btn.connect('pressed',self, '_on_open_info_race_buy', [race, race_info[2]]) #Set up the button with race ID  + cost.

pass

Ok so nothing special right ? Get the argument, read the informations depending of the race, set the button to signal : _on_open_info_race_buy(arg1,arg2)

Function _on_open_info_race_buy :

func _on_open_info_race_buy(race, cost): # Actually buying the race : Debit gold / add race to race owned.
print(race)
print(cost)
$unlock_race.hide()

in this function im doing nothing for the sake of this example.
The problem here is RACE and COST are only showing the argument the first time i load the 1st pop up with _on_open_info_race() - I dont even need to click the button.

example :
I open the pop up race id 2; i close it (just hide)
I open race 3. (It’s displaying race 3 information, so the argument race is good), I buy race 3.
But it shows that it’s buying race 2 and cost of race 2.

And I have no idea how to fix it.

Will record a video to maybe help with the explanation… Please let me know if i can provide any extra information.

EDIT : here is the video :
Human = 1 cost 0.
Orcs = 2 cost 2000
Nagas = 3 cost 3000
Demons = 4 cost 4000

As you can see, it will always show the first race i opened : 2/2000 (look into the console bottom left)

EDIT 2 :
I have tried to call the function manually rather than with my “pressed” button :

_on_open_info_race_buy(race, race_info[2])

And this works perfectly fine. No matter the race. So I’m assuming that there is something wrong wit my button ? Any idea ?

:bust_in_silhouette: Reply From: timothybrentwood

I think you should be getting debug warnings in your console for calling connect() on the same button multiple times. Change

$unlock_race/frame/btn.connect('pressed',self, '_on_open_info_race_buy', [race, race_info[2]])

to:

if $unlock_race/frame/btn.is_connected('pressed',self, '_on_open_info_race_buy'):
    $unlock_race/frame/btn.disconnect('pressed',self, '_on_open_info_race_buy')
$unlock_race/frame/btn.connect('pressed',self, '_on_open_info_race_buy', [race, race_info[2]])

That way the button is only connected to one signal at a time.

The way I would prefer to solve this would be to attach a script to that button with current_race and current_cost (or whatever) variables then set those variables with the return data from _race_info() instead of calling connect(). That way you just connect() the signal in _ready() and the button owns the data it needs to execute the function. When you hide() that popup just null out those variables to prevent future errors, if there are multiple hands in the cookie jar.

Thank you so much for your input. I will give it a shot after diner.
I have not seen yet “a script attached to that button”
Do you happen to have a super basic example ?

quizzcode | 2021-08-25 03:47

Actually after re-reading the code, since you’re connecting to self just make the variables member variables in that script (declared outside of a function). And since you already have the cost stored you can just access it via $unlock_race/frame/btn/text.text, so you would only need a currently_selected_race member variable. (I shouldn’t answer these when I’m tired XD )

You can attach a script to any node. Connecting a script to a button is the same as connecting a script to any other node. You press the add script button icon thingy in the SceneTree portion of the editor (top left by default).

timothybrentwood | 2021-08-25 04:17

“You press the add script button icon thingy in the SceneTree portion of the editor (top left by default).”
Oh that’s what you meant, i thought there was a way to add it from the script I was working with. I was confused. Yes of course I know how to do this :stuck_out_tongue:

I will try your approach. Thanks !

(good night :slight_smile: )

quizzcode | 2021-08-25 04:40

Alright ! So that did not work.
But the DISCONNECT function from btn, after clicking on it worked !
Thank you very much for your input

quizzcode | 2021-08-25 04:46

Here is how you would implement the solution I suggested

var currently_selected_race = null

func _ready():
    $unlock_race/frame/btn.connect('pressed',self, '_on_open_info_race_buy')

func _on_open_info_race(race): # BUY RACE 
    var race_info = Globals._race_info(race) #race informations
    $unlock_race/frame/title.text = str(race_info[0]) #Title of the race
    $unlock_race/frame/description.text = str(race_info[1]) #Description of the race
    $unlock_race/frame/btn/text.text = str(race_info[2]) #Cost of the race

    $unlock_race.show() #display the pop up with these infos,

    currently_selected_race = race

func _on_open_info_race_buy(): # Actually buying the race : Debit gold / add race to race owned.
    print(currently_selected_race)
    print($unlock_race/frame/btn/text.text)
    $unlock_race.hide()

timothybrentwood | 2021-08-25 14:41