How would one go about making a slide mechanic?

So I am working on a game and I want to add a slide mechanic. When a player presses a key, I want the player to slide so the player can slide under a wall or slide down a slope. I know obviously it would involve animations but how would I detect a slope and make it push the player forward when sliding. Any ideas to help push me in the correct direction?

1 Like

For detecting if the player is on a slope, you can use the dot and cross products. You’d have to cast a ray downwards and if the ray hit, you can get the surface normal of the intersection, then you’d cross it with the global right vector (1, 0, 0) and use the dot product on that vector to get the angle. This should be in a Heartbeat event:

local incline =, 0, 0):Cross(normal)

if incline.magnitude == 0 then
    incline =, 0, 0)

local angle = math.acos(, 1, 0):Dot(incline))

if angle > math.pi / 1.5 then
    -- slope

May need to mess with the angle to get correct result

For making the player move down the slope, you can get the initial position which is where the player first had contact with the slope and you can make a variable called velocity which is the velocity that the player will travel down the slope. dt, which is delta time (change in time from the last frame) is a parameter returned in the Heartbeat event

local velocity = 60 -- player will travel at 60 studs / s
HumanoidRootPart.CFrame = + (incline * velocity * dt)

I thought it seemed like it only slid in the one direction, so I checked the incline-
every slope returns the same direction, do you have a method that can check the angle of a rotated surface?

Nevermind- I was able to fix it, by replacing your cframe code.

instead of doing the initial + incline&speed,
I simply moved it by the HumanoidRootPart’s current position + normal * speed, allowing for a slide with scaling speed across slopes, and that follows the angle the slope is facing.

local velocity = 60 -- player will travel at 60 studs / s
HumanoidRootPart.CFrame =*velocity*dt)

for extra measures, I wanted to make sure that no slope below a certain angle would slide, but yours seems to only function on one direction- so I used math.abs to ensure the normal values were positive, then check the scale of the slope.

local spd = math.abs(normal.X) + math.abs(normal.Z)
if spd > 0.25 then

thus my “spd” variable would measure how tilted it was from a scale of 0-2, combining both horizontal and vertical rotation.