Movement System issue

I would like the player to slide of ledges (places where the Y level is higher than its surrounds).

I have looked for other solutions on the Developer Hub but nothing seems to match my problem.

local CAS = game:GetService("ContextActionService")
local UIS = game:GetService("UserInputService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local tweenservice = game:GetService("TweenService")
local char = script.Parent

local slideAnim = script.SlideA
slideAnim.AnimationId = tostring(script:WaitForChild("SlideA").AnimationId)

local keybind = Enum.KeyCode.C
local shiftKey = Enum.KeyCode.LeftShift
local crouchKey = Enum.KeyCode.C
local acceleration = 35
local tweenedTransition = false
local slideControlFactor = 0.05  -- Adjust this value to change how much A/D affect the slide direction

local hrp = char:WaitForChild("HumanoidRootPart")
local hum = char:WaitForChild("Humanoid")
local slidingAttachment = Instance.new("Attachment")
slidingAttachment.Name = "SlidingAttachment"
slidingAttachment.Parent = hrp

local alignOrientation = Instance.new("AlignOrientation")
alignOrientation.Enabled = false
alignOrientation.RigidityEnabled = not tweenedTransition
alignOrientation.Mode = Enum.OrientationAlignmentMode.OneAttachment
alignOrientation.Attachment0 = slidingAttachment
alignOrientation.Parent = hrp

local canslide = true
local sliding = false
local shiftPressed = false
local controlPressed = false
local crouchPressed = false

local leftPressed = false
local rightPressed = false

-- Preload slide animation
local playAnim = hum:LoadAnimation(slideAnim)
playAnim.Looped = true

-- Create RaycastParams once to avoid recreating it every frame
local params = RaycastParams.new()
params.FilterDescendantsInstances = {char}
params.FilterType = Enum.RaycastFilterType.Exclude

local equippedTool = nil

local function stopSliding()
	if not sliding then return end
	sliding = false
	alignOrientation.Enabled = false
	hum.AutoRotate = true

	hum:ChangeState(Enum.HumanoidStateType.GettingUp)
	playAnim:Stop(0.5)
	hum.CameraOffset = Vector3.zero

	-- Re-equip the tool if it was equipped before
	if equippedTool then
		hum:EquipTool(equippedTool)
	end

	task.wait(0.5)
	canslide = true
end

local function slideFunc()
	if not canslide or hum.Health <= 0 or hum:GetState() ~= Enum.HumanoidStateType.Running or hum.WalkSpeed < 10 or hrp.Anchored then
		return
	end

	canslide = false
	sliding = true
	alignOrientation.Enabled = true
	hum:ChangeState(Enum.HumanoidStateType.Physics)

	hrp.AssemblyLinearVelocity = hrp.CFrame.lookVector * acceleration
	hum.AutoRotate = false
	hum.CameraOffset = Vector3.new(0, -2.5, 0)

	-- Store the tool that is currently equipped
	equippedTool = nil
	for _, tool in ipairs(char:GetChildren()) do
		if tool:IsA("Tool") and tool.Parent == char then
			equippedTool = tool
			break
		end
	end

	hum:UnequipTools()
	playAnim:Play()
	script.Slide:Play()

	-- Reduce stamina on slide activation

	while sliding and hrp.Velocity.Magnitude > 0.1 do
		-- Adjust the shake intensity based on current speed
		local speed = hrp.AssemblyLinearVelocity.Magnitude
		local intensity = speed / 100  -- You can adjust the divisor to scale the intensity

		task.wait()
	end

	stopSliding()
end

local function onInputBegan(input, gameProcessed)
	if input.KeyCode == shiftKey then
		shiftPressed = true
		if crouchPressed then
		end
	elseif input.KeyCode == crouchKey then
		controlPressed = true
		if shiftPressed and not gameProcessed then
			slideFunc()
		end
	elseif input.KeyCode == Enum.KeyCode.A then
		leftPressed = true
	elseif input.KeyCode == Enum.KeyCode.D then
		rightPressed = true
	end
end

local function onInputEnded(input, gameProcessed)
	if input.KeyCode == shiftKey then
		shiftPressed = false
		if sliding then
			stopSliding()
		end
	elseif input.KeyCode == crouchKey then
		controlPressed = false
		if sliding then
			stopSliding()
		end
	elseif input.KeyCode == Enum.KeyCode.A then
		leftPressed = false
	elseif input.KeyCode == Enum.KeyCode.D then
		rightPressed = false
	end
end

UIS.InputBegan:Connect(onInputBegan)
UIS.InputEnded:Connect(onInputEnded)

local tweenInfo = TweenInfo.new(0.1)

game:GetService("RunService").RenderStepped:Connect(function()
	if not sliding then return end

	local result = workspace:Raycast(hrp.Position, Vector3.new(0, -4.5, 0), params)
	local linearVelocity = hrp.AssemblyLinearVelocity

	if result then
		hrp.AssemblyLinearVelocity = linearVelocity - result.Normal * linearVelocity:Dot(result.Normal)
		alignOrientation.CFrame = CFrame.lookAt(Vector3.zero, hrp.AssemblyLinearVelocity)

		local currentRightVector = hrp.CFrame.RightVector
		local upVector = result.Normal
		local newFacialVector = currentRightVector:Cross(upVector)
		local tween = tweenservice:Create(alignOrientation, tweenInfo, {
			CFrame = CFrame.fromMatrix(hrp.Position, currentRightVector, upVector, newFacialVector)
		})
		tween:Play()
	else
		hrp.AssemblyLinearVelocity = Vector3.zero
	end

	-- Adjust direction based on player input
	local slideDirection = hrp.CFrame.lookVector
	if leftPressed then
		slideDirection = slideDirection - hrp.CFrame.RightVector * slideControlFactor
	elseif rightPressed then
		slideDirection = slideDirection + hrp.CFrame.RightVector * slideControlFactor
	end

	-- Normalize slide direction to ensure it stays on the slope
	slideDirection = (slideDirection - result.Normal * slideDirection:Dot(result.Normal)).Unit
	hrp.AssemblyLinearVelocity = slideDirection * hrp.AssemblyLinearVelocity.Magnitude
end)
![2024-06-07-14-09-45_3xa9eFln|video](upload://8KnnXbovqVu3x7qDfb1YMhAhE0B.mp4)

1 Like


Video !

1 Like

I dont sure but maybe the “char” line

local char = script.Parent

What fix do you think I can do?

1 Like

I think just change variable name, not sure its the error tho, Haven’t looked in code really

1 Like

I think the problem is that you are raycasting down from the root part, and right before the player slides off, the root part no longer returns a hit but the player is still on. And also you set the player’s velocity to 0 (which you should avoid directly setting the velocity in the first place) when the ray stops hitting something. I think the solution would be when the ray no longer hits something, start a timer and delay the stop. You could also try just removing where you set the root part’s velocity to 0.

2 Likes

Alright, I’ll try that! Thanks for the suggestion!

1 Like

Thank you so much! I removed the part where I set the root part’s velocity to 0 (at lines 166 to 167 of the original script) and that fixed it!

2 Likes

Yeah directly setting velocity to 0 can result in some weird stuff, best to stay away from doing that.

2 Likes

Alright. Thanks for telling me.

1 Like

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