How would I change the player's velocity based on the slope of the floor

Essentially what I want to accomplish is to make the player automatically slide down any slope, and change the speed of the Body based on the steepness.

I honestly have no way to go about this, and I’m struggling to discover the functions and properties required to do this. I assume you would first calculate the normal of the floor via raycasting to see if it’s a slope or not so I already did that, but making them slide down anything that’s a slope is hard for me to imagine. Just for some background information, I started coding super recently so I’ve never used normals or BodyVelocity before.

Also I’m not super sure about what normals even are, but I know that they’re used for seeing if a surface is straight or not. Some explanation about normals would also be a great help.

Here’s a short explanation about normals. The normal of a vector is a vector that is perpendicular to that vector (there’s a 90 degree angle between their directions). The normal of a surface is a vector that is perpendicular to the lines that connect the vertices of that surface.

I believe you could calculate the velocity this way. If my calculations are correct, the resulting vector should be a normal of the surface normal. The normal in the variable names is the surface normal.

local MAX_SPEED = 10

local function getSlideVelocity(normal)

    local normalX, normalY, normalZ = normal.X,  normal.Y, normal.Z

    local normalHorizontalLength = math.sqrt(normalX^2+normalZ^2)
    if normalHorizontalLength < 1e-5 then
        return Vector3.new()
    end

    local dirX = normalX/normalHorizontalLength*normalY
    local dirZ = normalZ/normalHorizontalLength*normalY
    local dirY = -normalHorizontalLength

    local dir = Vector3.new(dirX, dirY, dirZ)
    local angle = math.atan2(dirY, normalY)
    return dir*(math.sin(-angle)*MAX_SPEED)
end

What about Humanoid.MaxSlopeAngle ?

I understand most of it, but can you explain why you needed the tangent and sine? I’ve never used sine or cosine or anything like that in my code before.

I don’t know if this will work, however it seems to make sense in my head. If we get the vector parrellel to the slope, then we can get the direction the player is sliding in, after that calculate the angle between the global up vector and the slope normal. Then use this angle and direction to give some velocity to the player.

-- Where up is a normalized vector representing the up vector of the player
local function getSlideVelocity(normal,up)
     local dot =  Vector3.new(0,1,0):Dot(normal)) --  angle of slope to vertical
     local angle = math.acos(dot)
     local groundParallel = up:Cross(normal); 
     local slopeParallel = groundParallel:Cross(normal);
     return (angle/math.pi) * MAX_SPEED * slopeParallel.Unit
end  

Of course, if you wanted to add a check too make sure it can only slide on certain steepness levels, you can check if the angle of the normal to the vertical reaches or doesn’t reach a certain threshold.

I’m pretty sure you can use HumanoidRootPart and CurrentCamera. (similar to how the ‘Head faces where camera is facing’ mechanic)