# How do I stay on steep slopes with move_and_collide()?

4.2.2

### Question

I am currently replicating 2d sonic physics, and I am struggling to figure out how to stay on slopes with move_and_collide(). In the 2d Sonic games, the player would always stay on slopes unless they jumped, ran off a ramp, or ran too slow. My code works fine for concave slopes, but the player falls off convex slopes when they get too steep (about 45 deg). I would use move_and_slide() if I could, but it doesn’t work with a different part of my code. Is there any way I could make this work?

Hard to say what’s going wrong without seeing some relevant snippets of code.

You might be interested in this paper about collision detection and sliding. It’s not engine-specific, and assumes no built-in collision handling, but you can probably look at the parts that deal with sliding and implement something like it on top of `move_and_collide`, if you want functionality like `move_and_slide`, but customized in some way.

Maybe you can use the last collided surface’s normal as a influence on direction

``````var floor_forward = last_collision.get_normal()
floor_forward = Vector2(floor_forward.y, -floor_forward.x) # turn 90 degrees right

velocity = floor_forward * input * speed

last_collision = move_and_collide(velocity * delta)
``````

I figured it out. I added two raycasts that extend below the player. Then I used them when my original two raycasts failed. If one of them was colliding while grounded, I set my grounded variable to true.

``````var collisionA = sensorA.is_colliding()
var collisionB = sensorB.is_colliding()
var collisionA1 = sensorA1.is_colliding()
var collisionB1 = sensorB1.is_colliding()

if collisionA or collisionB:
grounded = true
elif collisionA1 or collisionB1:
if !inAir:
grounded = true
else:
grounded = false
``````