How do I fix my mid-air dash?

Attention Topic was automatically imported from the old Question2Answer platform.

I managed to code a mid-air dash to my Megaman X-inspired game,but there’s a problem. The character basically teleports from point A to point B,instead of going from point A to point B quickly. Is there a way I can code my mid-air dash in a way the character moves in a straight line (without being affected by gravity) from point A to point B without being a teleport?

Here’s the code I have so far (I’m using GDScript):

`extends KinematicBody2D

var MOTION_SPEED = 100 * 2
var DASH_SPEED = 2
const JUMP_SPEED = 600
var velocity = Vector2()
var is_moving = false
var facing_x = 1
var is_dashing = false
var timer = 0
var dash_direction = 1
var midair_dash = 0

func _physics_process(delta):
var motion = Vector2()
var leftBool = Input.is_action_pressed(“left”)
var rightBool = Input.is_action_pressed(“right”)
var left
var right

``````if !leftBool:
left = 0
else:
left = 1

if !rightBool:
right = 0
else:
right = 1

var x_direction = right - left
motion += Vector2(x_direction,0)

if !(x_direction == 0):
is_moving = true
facing_x = x_direction

velocity.y += (gravity * 15 ) * delta
velocity = move_and_slide_with_snap(velocity, Vector2.DOWN, Vector2.UP)
if is_on_floor() and Input.is_action_just_pressed("jump"):
velocity.y = -JUMP_SPEED
if Input.is_action_just_released("jump") and velocity.y <= 0:
velocity.y = 0

if is_on_floor():
midair_dash = 0

if timer > 0:
if is_on_floor():
timer -= 1
DASH_SPEED = 2
else:
timer = 1
DASH_SPEED = 0.5
motion += Vector2(DASH_SPEED*dash_direction,0)
elif Input.is_action_just_pressed("dash"):
if is_on_floor():
timer = 20
dash_direction = facing_x
if Input.is_action_just_pressed("left") and facing_x == 1:
motion = Vector2(0,0)
if Input.is_action_just_pressed("right") and facing_x == -1:
motion = Vector2(0,0)
else:
if midair_dash < 1:
midair_dash += 1
motion += Vector2(50*facing_x,0)

motion = motion * MOTION_SPEED

move_and_slide(motion)`
``````

Is there any reason why you’re calling `move_and_slide` twice? The `is_on_floor()` functions will update only on the next frame regardless, just use it once with proper UP vector provided. I’m not an expert by any means, but as far as I know the best practice is to just calculate the motion throughout the whole code and just execute it using `move_and_slide` or `move_and_slide_with_snap` at the end.

I really don’t get why you’re trying to apply gravity separately from the rest of the movement. I’m not exactly sure what’s causing the unexpected behavior, but if I were you, I’d just rewrite it and clean it up to only have a single `motion` variable (instead of separate motion and velocity, whatever they may mean) and a single `move_and_slite`.

Elkondo | 2020-04-24 22:09

I’m getting started now,so basically I barely have any idea of what I’m doing lmao. I wanted my character’s speed to be constant even when dashing,without any variation,but I also wanted a smooth jump,so I copy+pasted the jump code from the Kinematic Character 2D template and someone helped me to code the horizontal movement alongside the dash.

I could rewrite the code,but the problem is I have no idea how I could clean my code. As I said,I just got started. The two move_and_slide commands are copy+pasted from codes from Godot templates,and my game doesn’t properly work without them in place,and I don’t know how to make it work while only calling it once.

The is_on_floor() functions will update only on the next frame regardless, just use it once with proper UP vector provided.

I don’t know what you mean by that,sorry. Could you elaborate?

Harmonikinesis | 2020-04-24 23:18

Ok, so first of all, if you’re new, it’s much better to start by following some youtube tutorials than by just copying code. It’ll be slower, but the tutorial will explain exactly what each line means and why it’s there.

The two `move_and_slide` commands probably aren’t an error, but I’d rather do without them.
In your `physics_process` function, you first calculate the direction the player is moving and save it as X coordinate of your ‘motion’ variable. That’s perfectly fine.
Next, you calculate gravity, but for some reason, instead of saving it as the Y coordinate of your motion variable, you save it as a separate one and execute it instantly with `move_and_slide_with_snap()`.
You later do some checks for dash etc. and replace the regular movement with the dash one for a certain period of time.
And finally, the horizontal movement is executed with `move_and_slide()`.

What I would change is instead of saving the gravity to the ‘velocity’ variable, just save it to the motion variable again and get rid of the first `move_and_slide_with_snap`. Then later, in your dash code, you’ll be able to simply set motion.y to 0, meaning you’ll remove whatever influence gravity had on player’s movement.
Also, you’ll need to replace `motion = motion * MOTION_SPEED` with `motion.x = motion.x * SPEED`, so that the MOTION_SPEED variable only affects the horizontal speed, not vertical.

As for your question, when you’re making a 2D platformer, `move_and_slide()` requires second parameter - an UP vector. Functions like `is_on_floor()` need to somehow check which direction the floor is. Maybe you’re making a ninja game when the player’s running upwards, or maybe the gravity is inverted, the game doesn’t know that unless you tell it.
So when you use `move_and_slide()` you need two parameters: first is the motion vector, which tells it which direction to move the object it’s controlling (here: the player). The second tells it which way is UP, so it can perform correct floor and ceiling checks for those functions I mentioned.
So in your case, the correct way to use it would be `move_and_slide(motion, Vector2.UP)` or `move_and_slide(motion, Vector2(0, -1))` or `move_and_slide(motion, Vector2.UP)`. The latter works, since Godot knows it’s a commonly used value and they just have it preset. You actually did use that unknowingly in `move_and_slide_with_snap` in your code already.

Hope that clears it up a bit. Now go and follow some tutorial so that you actually know what you’re doing next time

Elkondo | 2020-04-25 20:04