I am working on a racing game of sorts in which the timer (scoring system) is supposed to start when you cross the starting line (area2d). I kind of patched in the timer from a different game I made where it worked fine, but the difference is the timer is no longer starting on the ready function. I should mention that the timer uses its own script seperate from the gameManager. Here are the snippets of my script involved:
#MAIN
func start_timer_and_activate():
if timer_started == false:
timer_started = true
func _on_start_line_body_entered(body: CharacterBody2D) -> void:
print("Body Entered")
if body.is_in_group("player"):
print("Body Registered as Player")
start_timer_and_activate()
#TIMER
extends Control
@onready var label = $CanvasLayer/Label
@onready var timer = $CanvasLayer/Timer
@onready var total_time: int = 0
func _ready() -> void:
print("Timer Ready")
if GameManager.timer_started:
print("Timer Started In Ready")
$CanvasLayer/Timer.start()
func _process(delta: float) -> void:
if GameManager.timer_started == true:
print("Timer Actually Started")
$CanvasLayer/Timer.start()
set_process(false)
func _on_timer_timeout() -> void:
if GameManager.game_finished == false:
total_time += 1
var m = int(total_time / 60)
var s = total_time % 60
$CanvasLayer/Label.text = str(m).pad_zeros(2) + ":" + str(s).pad_zeros(2)
elif GameManager.game_finished == true:
GameManager.last_time = total_time
if GameManager.last_time < GameManager.best_time or GameManager.best_time == 0:
GameManager.best_time = GameManager.last_time
Any feedback helps I’ve been struggling with this for hours. Thanks!
Did you connect the timeout signal of the timer? There is nothing in code about connecting, so you should have connected it through the editor. Can you show a screenshot of the connection (the green arrow symbol next to the _on_timer_timeout() function).
Also, please edit your post to show the code snippets as preformatted code between three backticks ``` on both sides. This will make it more readable, otherwise it’s not possible to derive correct code logic from the snippet you sent.
I formatted the code in snippets, thanks for telling me how this is my first time using the forums. I cannot post a screenshot because I am a new user and it is blocked, but I can tell you that there is the symbol displaying the code is connected to _on_timer_timeout() and also _on_start_line_body_entered(). Another thing I found that I thought might be important was that every frame, the GameManager’s timer_started reverts back to false right after it becomes true. I cannot figure out why for the life of me though, as I looked through all the code and used the search function and timer_started only appears three times, two of which you can see, and once when it is declared where it is not even assigned a value just the typing :bool (and even when assigned to true for testing purposes it still reverts to false). You can see the entire timer script to see if it would be from there.
Thanks.
Can you add a print statement here, e.g. like that:
func start_timer_and_activate():
print("start_timer_and_activate")
if timer_started == false:
timer_started = true
And see if this is printed just once, or twice?
If it’s printed twice, it might be that you duplicated your GameManager node - one through the ProjectSettings, and again by adding it into your main scene.
That might not be true though, it’s just my hunch.
It’s probably better to test this by printing something in the GameManager’s _ready() function, because start_timer_and_active() might not get called on the duplicate.
func _ready() -> void:
prints("GameManager is ready!", get_path())
Timer Ready
GameManager is ready! /root/Node
Body Entered
Body Registered as Player
start_timer_and_activate
I also received this error:
E 0:00:04:0962 emit_signalp: Error calling from signal 'body_entered' to callable: 'Node2D(GameManager.gd)::_on_start_line_body_entered': Cannot convert argument 1 from Object to Object.
<C++ Source> core/object/object.cpp:1200 @ emit_signalp()
This sort of makes sense to me because I originally had it as the scene that opens on start, but later added a start menu; so upon pressing the start button in game, the scene is switched to the main scene (which has gameManager attached to it), but gameManager is also a global script in project settings. Not sure if I’m quite understanding, but maybe worth mentioning.
Your autoload nodes (like the GameManager) shouldn’t be part of any scenes that you load into your game, because these nodes are already automatically loaded into the tree when you start the game. So when you add them to the scene, it will just be a duplicate which you don’t need.
Can you remove the GameManager node from the scene that you load with the start button and leave only the one that is in the ProjectSettings? and see if this will fix your problem?