Hi there! I Have a pick up-able power up, that increases my speed for 15 seconds. When the timer runs out, it resets my speed and removes the power-up. But as long as the timer has not run out, I can’t remove the power-up from the screen, so I try to disable the collision on the power up and turn it invisible.
The power up turns invisible, but the collisions won’t be disabled. I log every time I pick it up and I see my speed increasing and resetting my timer each time I pick it up again.
For now I have solved it using a boolean variable but this seems like an unnecessary step and I feel like disabling the collision should just do the trick.
This is my code:
extends Powerup
var isApplied = false
@export_range(1, 2) var speed_multiplier: float = 1.2
@onready var duration = $Duration
@onready var collision = $CollisionShape2D
func apply_power_up(player: Spaceship):
if isApplied:
return
isApplied = true
collision.disabled = true
visible = false
duration.start(15)
player.change_speed(speed_multiplier)
func _on_duration_timeout():
spaceship.reset_speed()
isApplied = false
queue_free()
I’d suggest you change the change_speed method on player so that you can specify the duration in addition to the speed (e.g. player.change_speed(speed_multiplier, 16) and get_tree().create_timer can be called inside change_speed) - and then call queue_free() on the powerup immediately after. No need to keep the whole thing around if all you need is a timer.
In other locations throughout my code, I’ve tried the deferred way, but that happens at the end of the tick which for some use cases is not good enough such as a bullet that hits multiple (overlapping) hurtboxes. Here however, I think it would work
Very interesting solution. can I also apply this technique in an autoload or is this not possible since the autoload is not in a tree / scene?
And do I need to specify it’s a one shot or not?
Sorry for the late reply, you’ve probably already worked out a solution by now, but just to answer your question:
It should be fine to use an autoload because it’s the scene tree itself that actually creates the timer, and timers created in this way can in fact only be one shot because they are freed after the timeout event.