Sliding Slope Speed Adjustment Function

I am trying to get this function to properly adjust the velocity of the player based off of the slope of the part the player is on.

The issue is that the player’s velocity quickly falls down to sub 1 values on the X and Z. These values are maintained until the player stops being on a slope. So a slide on a flat surface terminates quickly.

I have tried using values like 1.1 and 0.9 instead of calculating them and it has yielded the same issue.

Here is my code:

	local function applyVelocityDecay()
			character.Humanoid.WalkSpeed = 0
			
			local currentVelocity = character.HumanoidRootPart.Velocity
			local verticalVelocity = currentVelocity.Y

			-- Raycast downwards from the HumanoidRootPart to get the surface normal
			local raycastParams = RaycastParams.new()
			raycastParams.FilterType = Enum.RaycastFilterType.Exclude
			raycastParams.FilterDescendantsInstances = {character}
			local raycastResult = workspace:Raycast(character.HumanoidRootPart.Position, Vector3.new(0, -10, 0), raycastParams)

			local surfaceNormal = Vector3.new(0, 1, 0) -- Default to upward normal
			if raycastResult then
				surfaceNormal = raycastResult.Normal
			end

			-- Calculate the slope angle from the character's CFrame and the surface normal
			local rootCFrame = character.HumanoidRootPart.CFrame
			local slopeAngleRad = math.acos(rootCFrame.LookVector:Dot(surfaceNormal))
			local slopeAngleDeg = math.deg(slopeAngleRad)
			
			
			-- Adjust decay/acceleration rate based on the slope angle
			if slopeAngleDeg >= 80 and slopeAngleDeg <= 100 then -- Between 80 and 100 degrees normal decay
				
				decayRate = defaultDecay
				
			elseif slopeAngleDeg > 100 then -- more than 100 degrees
				
				local decayFactor = 2 - (slopeAngleDeg / 100)  -- decay rate is 1 to 0.2
				decayRate = defaultDecay * decayFactor
				
			elseif slopeAngleDeg < 80 then
				
				local accellFactor = 1 + ((1 - (slopeAngleDeg / 100)) / 2)  -- accel rate is 1.1 to 1.5
				decayRate = defaultDecay * accellFactor
			end

			-- Apply decay/acceleration to velocity
			local newVelocity = Vector3.new(currentVelocity.X * decayRate, verticalVelocity, currentVelocity.Z * decayRate)
			character.HumanoidRootPart.Velocity = newVelocity

			-- Adjust slide direction based on character's look vector and input delta
			local lookVector = character.HumanoidRootPart.CFrame.LookVector * Vector3.new(1, 0, 1)
			character.HumanoidRootPart.Velocity = character.HumanoidRootPart.Velocity + lookVector * input.Delta.X + lookVector * input.Delta.Z
			print(character.HumanoidRootPart.Velocity)
			-- Stop the sliding animation if velocity is nearly zero
			if newVelocity.Magnitude < 2 then
				sliding:Stop()
				character.Humanoid.WalkSpeed = walkSpeed.Value
				character.HumanoidRootPart.Velocity = Vector3.new(0, 0, 0) -- Ensure to stop any movement
				return true -- Return true to indicate that the decay process should stop
			end

			return false -- Continue decay process
		end

output:

1 Like

I found the solution, I used the initial velocity and modified that, and then I updated the player’s velocity to that every frame, otherwise, another script somewhere is overriding the velocity of the player. It’s probably the movement controller.

1 Like

I also changed the values to be constant for decay and acceleration, to 1.01 for acceleration, and 0.98 for flat, and then 0.95 for uphill.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.