time delay for action on buttons

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

Hi folks, I am trying to make my buttons jiggle after being pressed, and then after like 2 seconds then it would change the scene. What I am struggling with is what I think is the lack of a native time function. So I created a timer function as a global (since I would like to reuse the delay code in many buttons etc) but I am having an issue in which the timer code doesn’t trigger the chance scene code. If I place the timer contents directly into the button it works but if I try to make it a function that is hosted globally it doesnt. The function does get triggered but it does not call the action for the timer.

in global snippets:

extends Node
func _delay(delay,action):
	print("delay triggered")
	print(action)	
	var timer = Timer.new()
	timer.set_wait_time(delay)
	timer.set_one_shot(true)
	timer.connect("timeout", self, action)
	add_child(timer)
	return timer.start()

In button pressed:

func _switch_delay():
	BackSwitcher.switch_scene("res://scenes/jumble/jumble_menu_screen.tscn")
	pass
func _on_jumble_play_button_pressed():

	self.rect_scale.x = 0.2 + deg2rad(sin(2*time + 1))/2
	self.rect_scale.y = 0.2 + deg2rad(sin(2*time + 1))/2
	self.rect_position.x = start_x + ((self.rect_size.x * 0.2) - (self.rect_size.x * self.rect_scale.x))/2
	self.rect_position.y = start_y + ((self.rect_size.y * 0.2) - (self.rect_size.y * self.rect_scale.y))/2
	self.rect_rotation = 0 + deg2rad(sin(10*time + 15))
	snippets._delay(5.0,_switch_delay())
:bust_in_silhouette: Reply From: Gluon

You have connected the timers timeout to a function called action but you have a function called _switch_delay to change the scene.

have you tried changing this line

timer.connect("timeout", self, action)

to

timer.connect("timeout", self, "_switch_delay")

action is a placeholder which is calling _switch_dalay. See the last line of code:

snippets._delay(5.0,_switch_delay())

fungaim | 2022-01-10 09:51

Okay in that case you need to change that line of code too

snippets._delay(5.0,"_switch_delay")

Gluon | 2022-01-10 10:18

that doesnt get triggered still

fungaim | 2022-01-10 10:56

I think the issue is that I am referring to self but I don’t know how to refer to the original button object that was pressed here rather than the timer. in this line:

timer.connect("timeout", self, action)

fungaim | 2022-01-10 10:58

No self in this instance is telling the timer that when it gets the first signal timeout to do something. The second action signal is what it is supposed to do.

I rather suspect you are not including the quotation marks to make it a string or else you are putting () in with the call. Did you copy my line exactly? I have done exactly this many times and it always worked for me.

Gluon | 2022-01-10 14:17

You could try the below; making it an autostart rather than just starting it manually.

var timer = Timer.new()
timer.autostart = true
timer.set_wait_time(delay)
timer.set_one_shot(true)
timer.connect("timeout", self, action)
add_child(timer)

Gluon | 2022-01-10 14:20

Also is snippets a separate script?

Gluon | 2022-01-10 14:24

yes, snippets is a separate script. It’s a global one. The idea is that I will use the time delay function for other buttons and scenarios. So rather than adding the code directly in each item I use it in (which is working correctly), I would instead call the code in snippets and pass the relevant details needed (hence the doubt about self).
I didn’t add the autostart as I wanted the logic to be called specifically after pressing the button rather than when the object is rendered.

fungaim | 2022-01-10 16:52

:bust_in_silhouette: Reply From: chesse

Hello fungain,

as Gluon already mentioned you should use the function name for connect and not the function it self

<source_node>.connect(<signal_name>, <target_node>, <target_function_name>)

Also instead of creating your own logik, I think you could try to use an animation for your button jiggle and trigger the scene change on animation_finished.