Godot Version
4.3
Question
hi so i want to make the player move on a grid, and i wanted it to queue inputs while it’s animating the walking, so that if you quickly press ↑ thrice, it walks forward 3 turns, even tho twice you pressed it while it was already walking the first turn.
i tried to do this using a coroutine that waits for a signal that tells it what to do (emitted from _input
), does the movement, and then processes the next signal only after the movement animation has completed. however it doesn’t actually work the way i wanted - if i press a key while it’s animating, nothing happens after it finishes. i see the print_debug in _input
executes twice, but the one in walk
only once. so signal emissions are dropped while no one is waiting for it?
here is the script, it’s for a Node3D
but also expects there to be a child node Camera
extends Node3D
enum Movement {FORW, BACK, TURNL, TURNR, STRL, STRR}
signal move(m: Movement)
func _ready() -> void:
move_loop()
func _input(event: InputEvent) -> void:
if event.is_action_pressed("ui_up"):
print_debug("going froward")
move.emit(Movement.FORW)
elif event.is_action_pressed("ui_down"):
move.emit(Movement.BACK)
func move_loop():
while true:
var m = await move
print_debug("moving, ", m)
match m:
Movement.FORW: await walk(0, -1)
Movement.BACK: await walk(0, 1)
var step_size = 0.1
var step_time = 0.04
func walk(dx, dy):
var d = Vector3(dx, 0, dy).rotated(Vector3(0,1,0), -$Camera.rotation.y)
var pos0 = position
var steps = ceil(max(abs(d.x), abs(d.y)) / step_size)
var step: Vector3 = d / steps
for _i in range(steps - 1):
position.x += step.x
position.z += step.y # z is horizontal cuz we are in 3d
await get_tree().create_timer(step_time).timeout
self.position = pos0 + d
(in the end i fixed it in my code by removing the parameter from the signal, using an array as the queue and only using the signal to wake up the coroutine, i should’ve done it that way because i can actually limit the queue, but also i’d like to know, what’s with the signal in the code i sent here, is this a bug in the engine?)