This site is currently in read-only mode during migration to a new platform.
You cannot post questions, answers or comments, as they would be lost during the migration otherwise.
+1 vote

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

onready var gravity = ProjectSettings.getsetting("physics/2d/defaultgravity")
var MOTIONSPEED = 100 * 2
var DASH
SPEED = 2
const JUMPSPEED = 600
var velocity = Vector2()
var is
moving = false
var facingx = 1
var is
dashing = false
var timer = 0
var dashdirection = 1
var midair
dash = 0

func physicsprocess(delta):
var motion = Vector2()
var leftBool = Input.isactionpressed("left")
var rightBool = Input.isactionpressed("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)`
in Engine by (19 points)
edited by

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.

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 moveandslide 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 isonfloor() 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?

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 :)

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.