Godot Version
Godot 4.3 stable
Question
I added a timer to the Scene Tree, then added a reference of the Timer to my script. Then I connected the TimeOut signal to the player script but the _timer_timeout signal is not working.
My goal: when the player reaches the goal a Timer with 3 seconds starts and on TimeOut, the current scene should reload.
I start the Timer in the _ready( ) function and then call the TimeOut function at the bottom of the scrip. Here’s my script:
I checked and the signal seems to be connected, not sure what is happening but I’ll keep investigating. In the mean time if you see this post and want to help out, I’ll really appreciate it.
I do not know much about custom signals, but I’ll ask some probing questions that might help.
If the timer.start() isn’t working… what about the body.spinning = true?
That will help you determine if its being triggered or not.
For me, I would generally click on whatever “goal” is in my scene tree, go to signals, and do a body_entered() signal connect instead of trying to connect it with a ready function.
get_tree().reload_current_scene
is a value. If you want to call it as a function, you need brackets at the end:
get_tree().reload_current_scene()
1 Like
@ProjectMayhem First of all, thank you very much for replying to my post. To answer your question, yes the body.spinning = true is working but for some reason the timer.start( ) is not. Perhaps is not the timer.start( ) but the _on_timer_timeout( ) function that is not working properly with my current setup.
@hexgrid Thanks for your explanation, I just leaned something new. I did as you suggested but it’s still not working. I going to keep investigating in the mean time. If you need more information from my end to see what can be potentially happening, let me know. Thanks in advanced!
Please just post the code next time. Pictures of code are less than ideal and for some reason this one took forever to download.
The timeout signal callback does not have a parameter by default so unless you have bound one in the connection that function declaration will not match and may cause it not to get called.
However in that case you should be seeing an error like this:
emit_signalp: Error calling from signal ‘timeout’ to callable …
Are there any errors?
Do you connect the timer by code or via the editor?
1 Like
@sancho2 Thanks for your reply and also for your suggestion in regards of not uploading code pictures. I uploaded a picture thinking it was going to be easier to read since it has colors. Moving forward I will just paste the code.
In regards to your question: No, there are no errors & I connected the Timer via the editor.
Do you need the timer
parameter?
I doubt it since you can just drag the timer node into the code window and have class level access to it.
Click on the Timer node and drag it into the code window, hold ctrl and drop it at the top of the code.
@onready var timer: Timer = $Timer
And then get rid of the parameter:
func _on_timer_timeout()->void:
...
@sancho2 I did as you suggested but it still doesn’t work. Here’s my code:
@sancho2
class_name Player
extends CharacterBody2D
@onready var player: Player = %Player
@onready var goal: Area2D = $“…/Goal”
@onready var timer: Timer = %Timer
var max_speed := 600.00
var spinning: bool = false
var target: Node2D
var direction: Vector2
func _ready() → void:
goal.body_entered.connect(func(body: Node2D) → void:
if body is Player:
body.spinning = true
timer.start()
)
func _physics_process(_delta: float) → void:
var direction := Input.get_vector(“move_left”, “move_right”, “move_up”, “move_down”)
velocity = direction * max_speed
move_and_slide()
if spinning:
player.rotate(.1)
player.position = player.position.move_toward(goal.global_position, 10)
#this will force the player to stay in the middle due to the second argument in the line of code above. If the value is less than 10, the player will be able to slowly move away from the center.
direction -= player.position
func _on_timer_timeout() → void:
get_tree().reload_current_scene()
@sancho2 Once the player enters the ‘goal’ Area I want to start the timer and after 3 seconds when the Timer times out, then the scene should reload, that’s my goal.
There is a couple of concerns here:
class_name Player
extends CharacterBody2D
@onready var player: Player = %Player
There is not likely to be a need for the player variable as this entire class is the player variable. You can (in all likelihood) remove that variable.
So everywhere in the code where you use it you can remove the prefix. For example:
if spinning:
#player.rotate(.1)*
rotate(.1)
Ironically, your picture now does come in handy. I don’t see the signal connected symbol beside your code. It is pointed to in this image (from my code):
That tells me that your timeout signal is not connected to that function.
It may just be off screen in your picture. Double check that.
Put a breakpoint or print statement as the first line of the timeout function to be sure it didn’t get there.
And if still an issue, post a picture of your scene tree.
And also please wrap your code in the code tags. You can use the </> button in the text window you type your posts in.
1 Like
@sancho2 You were right, I have 2 functions with 2 different signals and the Timer TimeOut signal was not connected to the Player. I made the changes and now the Scene reloads after 3 seconds.
Also thank you for pointing out that there is no need for the player prefix since the entire class is the player.
I’m still fairly new to coding and GD Script. Most of the code I posted came from a course I’m taking plus some refactoring I’m doing on my own. Again, thanks for your help, now is working as intended. 