+2 votes

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")
    var timer = Timer.new()
    timer.connect("timeout", self, action)
    return timer.start()

In button pressed:

func _switch_delay():
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))
Godot version 3
in Engine by (14 points)
edited by

2 Answers

0 votes

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)


timer.connect("timeout", self, "_switch_delay")
by (1,369 points)

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


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


that doesnt get triggered still

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)

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.

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

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

Also is snippets a separate script?

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.

0 votes

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.

by (130 points)
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.