Detecting velocity against a slope (surface normal)

I’m trying to find the slope of an objects’ movement relative to it’s “forward” face. I’m trying to see how steep the current path is. I’ve tried comparing velocities and relative positions but those have tons of edge cases. I think what I need to do is take the surface normal of the “ground” underneath the object & do some dot product magic using the objects velocity? What would that look like.

5 Likes

One way I could think of is casting two rays under the character, seperated from each other by a magnitude of 1 stud, and the slope would be the first ray’s hit position’s Y component over the second ray’s hit position’s Y component.

hitunderslope

You can definitely use dot products, using the fact that the closer two unit vectors are to having the same direction, the closer the value gets to 1. Let a be the triangles norm facing upwards, and b the character UpVector, the more a:Dot(b) is less than one, the more steeper the slope is. The value would always be between 1 and 0 (technically 1 and -1, but since the triangle would never be facing upside down, the value wuld never be less than 0). 1 means it’s just a flat surface, 0.5 means it’s going 45 degrees, and the less it gets it’s steeper and the angle gets larger until it hits 0 which is essentially 90 degrees, like a wall. This would work but honestly it’s a bad representation of the slope. (e.g. a value from 0 to 1 is a bad representation).

1 Like

I was able to use the following code to print the slope of the surface that the character is walking on:

local character = game:GetService("Players").LocalPlayer.Character;
local humanoid = character.Humanoid;
local hrp = character.HumanoidRootPart;
local mask = Vector3.new(1,0,1);    --Used to isolate the X and Z components
while wait() do
    if humanoid.FloorMaterial~=Enum.Material.Air then    --Prevent jumping from messing up the result
        local deltaY = hrp.Velocity.Y;
        local deltaX = (hrp.Velocity*mask).Magnitude;    --Magnitude of horizontal velocity
        print(deltaY/deltaX);    --Rise/Run
    end
end

It’s mostly accurateIt’s very accurate for wedges, but this can only be run from the client (as the Velocity of the HumanoidRootPart isn’t replicated to the server).

EDIT: Corrected some mistakes (hopefully) pointed out by @starmaq :slight_smile:

3 Likes

Have you got an explanation why Velocity.Unit.Y describes a slope?

1 Like

Thanks for pointing it out. I’ve made some corrections to my code to print the correct slope. After testing it does print the slopes of various wedges I set up.

1 Like