Godot Version
4.7 (latest steam version)
Issue:
This is a pretty niche issue i haven’t been able to figure out, I have a custom timer system that allows a timer of set time to be started and then if it hasn’t ended by the time it runs out the player dies. this is used in-game as like a race thing where the player has to get to the end before the time runs out.
When the timer is active and the player dies, for some reason the signal related to the hitbox doesn’t kill the player after touching anything that should kill the player even though the timer doesn’t touch the signal, basically if you die with the timer active you become invincible.
if anyone could help then that would be like really appreciated, this is my first game that i started making and i haven’t worked on it for months and i’m coming back to finish it so i’m still getting re-used to the project if that makes sense
Relevant code:
timer system script:
extends CanvasLayer
@onready var timer_display: Label = $TimerDisplay
@onready var timer: Timer = $Timer
@onready var animation_player: AnimationPlayer = $AnimationPlayer
@export var timer_active:bool = false
var player:Player
var animation_check:bool
func _ready() -> void:
if get_tree().get_first_node_in_group("player") and get_tree().get_first_node_in_group("player") is Player:
player = get_tree().get_first_node_in_group("player")
timer_display.text = ""
animation_player.play("enter", -1, -10, true)
func _process(_delta: float) -> void:
if timer_active and timer.time_left > 0:
if animation_check == false:
animation_check = true
animation_player.play("enter", -1, 1.5)
timer_display.text = str(timer.time_left)
if player and player.dying:
end_timer()
if Input.is_action_just_pressed("Back"):
end_timer()
else:
if animation_check:
animation_check = false
if player and player.dying == false:
timer_display.label_settings.font_color = Color(0.0, 0.573, 0.0, 1.0)
animation_player.play_backwards("enter")
await animation_player.animation_finished
timer_display.label_settings.font_color = Color(1.0, 0.945, 0.91)
timer_display.text = ""
func start_timer(time):
if timer_active == true: return
timer_active = true
if timer.time_left == 0:
timer.start(time)
func end_timer():
timer_active = false
timer.stop()
func _on_timer_timeout() -> void:
if timer_active and player:
print("out of time")
player.die()
end_timer()
script for the level objects that trigger and stop the timer:
extends Area2D
@export var time:float = 30.0
@export var finish:bool = false
@onready var sprite: Sprite2D = $Sprite2D
func _ready() -> void:
if finish == false:
sprite.region_rect = Rect2(0,0,8,32)
else:
sprite.region_rect = Rect2(8,0,8,32)
func _on_body_entered(body: Node2D) -> void:
if not body is Player: return
TimerController.player = body
if finish == false:
TimerController.start_timer(time)
else:
TimerController.end_timer()
part of the player script that handles death and the signal from the hurtbox:
# handle death
func _on_hurtbox_body_entered(_body: Node2D) -> void:
print("dying maybe")
die()
func die():
if dying:
print("cant die")
return
dying = true
print("die")
WalkFx.emitting = false #particles
ColorFx.emitting = false
set_physics_process(false)
AudioController.play_die()
Camera.add_trauma(0.2) #screenshake
add_effect(ExplosionScene, true)
Sprite.visible = false
velocity = Vector2.ZERO
await get_tree().create_timer(0.4).timeout
get_tree().call_group("reset", "reset")
await get_tree().create_timer(0.1).timeout
position = Spawn.position
color = 0
Sprite.visible = true
set_physics_process(true)
can_change_color = true
dying = false
