I want to make a Megaman-like dash mechanic for my 2D platformer game, but right now, it's more like blinking instead of dashing. Basically, the player character will appear at the destination without traversing.

I made two scripts, but both scripts act like blinking.

func dash() -> void:
    var dash_velocity: Vector2
    
    if is_facing_right:
        dash_velocity = Vector2.RIGHT * dash_speed
    else:
        dash_velocity = Vector2.LEFT * dash_speed
    
    velocity.y = move_and_slide(dash_velocity, FLOOR_UP).y
    
    can_dash = false
    dash_cooldown.start()
func dash() -> void:
	var dash_velocity: Vector2
	
	if is_facing_right:
		dash_velocity = Vector2.RIGHT * (dash_distance / dash_time)
	else:
		dash_velocity = Vector2.LEFT * (dash_distance / dash_time)
	
	velocity.y = move_and_slide(dash_velocity, FLOOR_UP).y
	
	can_dash = false
	dash_cooldown.start()

generally I think you will only want to call move_and_slide() once in your code to handle your movement, so your dash should only be affecting the vector you input into that move in slide, it shouldn't have it's own. I think that might be what's causing your problem but I could be wrong.

If this is the only time you've called it and you just haven't programmed walking yet, please correct me =)

I'm currently using a state machine. So this dash function is on the player node.

    func dash() -> void:
        var dash_velocity: Vector2
        if is_facing_right:
            dash_velocity = Vector2.RIGHT * dash_speed
        else:
            dash_velocity = Vector2.LEFT * dash_speed
        velocity.y = move_and_slide(dash_velocity, FLOOR_UP).y
        can_dash = false
        dash_cooldown.start()
# Dashing.gd
extends PlayerState

func physics_update(delta: float) -> void:
	
	player.dash()
	
	if is_equal_approx(player.direction, 0):
		state_machine.transition_to("Idle")
	elif Input.is_action_pressed("left") or Input.is_action_pressed("right"):
		state_machine.transition_to("Moving")

Alright, I get it to work. I have to yield create_timer to make it work.

# Dashing.gd
extends PlayerState

func physics_update(delta: float) -> void:
	
	player.dash()
	
	yield(get_tree().create_timer(0.1), "timeout")
	
	if player.is_on_floor():
		if is_equal_approx(player.direction, 0):
			state_machine.transition_to("Idle")
		elif Input.is_action_pressed("left") or Input.is_action_pressed("right"):
			state_machine.transition_to("Moving")
	else:
		state_machine.transition_to("Aerial")

But... if you yield create_timer on the function, it won't work. I wonder why.

a year later