i'm trying to do a roll animation for a 2d platformer but it doesen't wrok right

Godot Version

4.5

i’m trying to make my character roll, and it kinda works, but every time i roll the next roll duration is cut in half and after 2/3 rolls i cant do them anymore, here is my code:
extends CharacterBody2D

const SPEED = 130.0
const JUMP_VELOCITY = -300.0

@onready var animated_sprite: AnimatedSprite2D = $AnimatedSprite2D
var is_rolling: bool = false

func roll():
is_rolling = true

var timer: Timer = Timer.new()
timer.wait_time = 1.0  # 1 second roll
timer.timeout.connect(roll_end)
add_child(timer)
timer.start()

func _physics_process(delta: float) → void:
# Add the gravity.
if not is_on_floor():
velocity += get_gravity() * delta

# Handle jump.
if Input.is_action_just_pressed("jump") and is_on_floor():
	velocity.y = JUMP_VELOCITY


# Get the input direction and handle the movement/deceleration.
# As good practice, you should replace UI actions with custom gameplay actions.
var direction := Input.get_axis("move_left", "move_right")
if direction:
	velocity.x = direction * SPEED
else:
	velocity.x = move_toward(velocity.x, 0, SPEED)

#movement
if is_on_floor() and Input.is_action_just_pressed("roll"):
	if Input.is_action_pressed("move_left") or Input.is_action_pressed("move_right"):
		roll()

if Input.is_action_just_pressed("move_left"):
	animated_sprite.flip_h = true
if Input.is_action_just_pressed("move_right"):
	animated_sprite.flip_h = false

#animations
if is_rolling:
		animated_sprite.play("roll")
elif is_on_floor():
	if direction == 0:
		animated_sprite.play("fermo")
	else:
		animated_sprite.play("corsa")
else:
	animated_sprite.play("salto")

move_and_slide()

func roll_end():
is_rolling = false
`

func roll():
	is_rolling = true
	var timer: Timer = Timer.new()
	timer.wait_time = 1.0  # 1 second roll
	timer.timeout.connect(roll_end)
	add_child(timer)
	timer.start()

Every time you roll, you create a new timer. By default, timer’s one_shot property is false, which means every timer will send its signal every second - and each of those signals is ending your roll.

Instead of creating the timer in the script, it’s probably easier to just add one to your scene in the editor, so you only have to start it in your roll() function.

thank you i’ll try

how can i do that if you already pressed the roll button it wont work unkess the animation is finished? bacuse if i spamm the button the animation doesnt play because it restart the action every time

You can add this at the beginning of the roll() function:

	if is_rolling:
		return

thank you very much

1 Like