Need help improving a sliding mechanic in my 2d game

Godot Version

4.2.2

Question

I’m trying to add sliding to my game. So far, I have kind of added it, you can slide on flat surfaces, but that’s about it. Right now, I’m trying to figure out how I could change my code so that I slide faster on slopes, but I’m struggling to figure it out. I also have a problem where my player moves backward by about a pixel every second. Here is my movement code. Any help would be great.

var direction = Input.get_axis("ui_left", "ui_right")

if (direction and sliding == false):
	velocity.x = direction * SPEED
elif !Input.get_axis("ui_left", "ui_right") and sliding == false:
	velocity.x = move_toward(velocity.x, 0, SPEED)
else:
	if velocity.x >= 0 and direction >= 0:
		`velocity.x -= 380 * delta`
	elif velocity.x <= 0 and direction <= 0:
		velocity.x += 380 * delta
	else:
		velocity.x = 0

move_and_slide()

if Input.is_action_pressed("slide") and velocity.x != 0:
	scale.y = 0.5
	sliding = true
elif Input.is_action_pressed("slide") and velocity.x == 0:
	scale.y = 0.5

(sorry for the mess im still new to GDS) (all of the code is under _physics_process )

What do you mean by ‘backward’? What are the backticks for in the

if velocity.x >= 0 and direction >= 0:
		`velocity.x -= 380 * delta`

block?
Further in the script, you have <= in the elif section. These shouldn’t matter, as if the velocity.x and the direction were equal to zero, it would be caught in the if, so they can just be <. In the if, you shouldn’t need to check for velocity.x relative to 0, as you can use

var x = velocity.x / abs(velocity.x)
if x
#you don't need to check direction, as it will be greater than, equal to, or less than 0,
#all of which lead to this line of code:
	velocity.x += 380 * delta

to create a multiplier and simplify some code. I personally have had issues with slopes in general. I haven’t tested this code, so it might not work.

P.S. I love your name

I’m having a bit of a hard time understanding what you responded with, if you could clarify where the second block of code should go that would help a lot, I have also found a problem where you can’t move at all after sliding and releasing the “slide” button, I think the problem is the sliding variable isn’t switching back to false after it becomes true but from what I understand it should, the problem would be in this block, but I’m really not sure what the problem is.

	if !Input.is_action_pressed("slide"):
		scale.y = 1
		sliding == false
	elif Input.is_action_pressed("slide") and velocity.x != 0:
		scale.y = 0.5
		sliding = true
	elif Input.is_action_pressed("slide") and velocity.x == 0:
		scale.y = 0.5
		sliding == false

also, im a fan of your name aswell

The problem with the slide button releasing is not quite what you think it is. On line 3,

	if !Input.is_action_pressed("slide"):
		scale.y = 1
#the line after this one
		sliding == false

and in the second elif, you say

sliding == false

The problem with this is that having both equals signs is a compare function, not an assignee. To check whether something is equal to something else, == is used, to set a variable, = is used.

Instead of your first post, this MIGHT work:

var direction = Input.get_axis("ui_left", "ui_right")


if (direction and sliding == false):
	velocity.x = direction * SPEED
elif not direction and sliding == false:
	velocity.x = move_toward(velocity.x, 0, SPEED)
else:
	#sliding == true?

	#a number from -1 to 1 based on the current velocity
	var x = velocity.x / abs(velocity.x)

	if direction - x == 0:
		#the reason direction - x works, is because you currently check if your direction and velocity
		#are going in the same direction, and 1 - 1 == 0 and -1 - -1 == 0

		#the * x is to flip left or right based on current velocity
		velocity.x += 380 * delta * x
	else:
		velocity.x = 0

move_and_slide()

if Input.is_action_pressed("slide") and velocity.x != 0:
	scale.y = 0.5
	sliding = true
elif Input.is_action_pressed("slide") and velocity.x == 0:
	scale.y = 0.5

again, this MIGHT work

Enjoy! :grinning:

i had no idea that == meant compare, i just thought it was a weird thing for if statements because why not.

sadly your version of my code does not work how i’d like it to so i think ill be sticking with what i wrote. i also know how it works more than i know yours so it will be easier for me to modify in the future.

also, i think i have an idea on how to get sliding to work on slopes: i use an area 2d under the player to get the angle of the slope, then multiply the rotation_degress and make it a minimum velocity. if you have any different suggestions on how to do this that would be great, but for now, thanks for all your help.

Keep your code, as it sounds like the better idea. For slopes, you probably don’t need an area2D, as the characterBody2D has a built-in get_floor_normal() function and a get_wall_normal() function, which will return the vector2 of the vector perpendicular to the floor/wall. Check this out for more info.

awesome, thanks

1 Like