Climb System not working

Hello everyone, I want to finish my climbing system but I can’t make the character move by pressing “w”, “s”, “a”, “d”. I already tried to use rays towards the 4 directions but it does not detect the edges that must be scaled. Here I leave my code, I hope you can help me.

local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local TweenService = game:GetService("TweenService")

local player = game.Players.LocalPlayer
local character = player.Character
local camera = workspace.CurrentCamera
local humanoid = character:WaitForChild("Humanoid")
local rootPart = character:WaitForChild("HumanoidRootPart")
local head = character:WaitForChild("Head")

local cameraShaker = require(game.ReplicatedStorage:WaitForChild("Modules").CameraShaker)

local function ShakeCamera(shakeCf)
	camera.CFrame = camera.CFrame * shakeCf
end

local renderPriority = Enum.RenderPriority.Camera.Value + 1
local camShake = cameraShaker.new(renderPriority, ShakeCamera)

local raycastParams = RaycastParams.new()
raycastParams.FilterDescendantsInstances = {character, workspace["Test Area"]}
raycastParams.FilterType = Enum.RaycastFilterType.Exclude

local vaultMoveNumber = 10
local canVault = true
local canMove = true
local vaultConnection = nil
local ledgePart = nil
local climbing = false
local wasLedgeNearby = false

local grabAnim = humanoid:LoadAnimation(script:WaitForChild("Grab"))
local grabRightAnim = humanoid:LoadAnimation(script:WaitForChild("GrabRight"))
local grabLeftAnim = humanoid:LoadAnimation(script:WaitForChild("GrabLeft"))
local grabSounds = script:WaitForChild("Sounds"):GetChildren()

local function playSound()
	local sound = grabSounds[math.random(1, #grabSounds)]:Clone()
	sound.Parent = rootPart
	sound.Volume = .15
	sound:Play()
	sound.Ended:Connect(function()
		sound:Destroy()
	end)
end

local screenGui = Instance.new("ScreenGui")
screenGui.Parent = player:WaitForChild("PlayerGui")

local ledgeIndicator = Instance.new("Frame")
ledgeIndicator.Size = UDim2.new(0, 200, 0, 50)
ledgeIndicator.Position = UDim2.new(0.5, -100, 0, 10)
ledgeIndicator.BackgroundColor3 = Color3.fromRGB(255, 0, 0)
ledgeIndicator.Visible = false
ledgeIndicator.Parent = screenGui

local function showLedgeIndicator()
	ledgeIndicator.Visible = true
end

local function hideLedgeIndicator()
	ledgeIndicator.Visible = false
end

local function partCheck(ledge)
	local vaultPartCheck = workspace:Raycast(ledge.Position + Vector3.new(0, -1, 0) + ledge.LookVector * 1, ledge.UpVector * 3, raycastParams)
	if vaultPartCheck == nil then
		return true
	else
		return false
	end
end

local function vaultMoveCheck(ray, anim)
	local localPos = ray.Instance.CFrame:PointToObjectSpace(ray.Position)
	local localLedgePos = Vector3.new(localPos.X, ray.Instance.Size.Y / 2, localPos.Z)
	local ledgePos = ray.Instance.CFrame:PointToWorldSpace(localLedgePos)
	local ledgeOffset = CFrame.lookAt(ledgePos, ledgePos - ray.Normal)

	if partCheck(ledgeOffset) then
		local magnitude = (ledgePos - head.Position).Magnitude
		if magnitude < 3 then
			local info = TweenInfo.new(.15, Enum.EasingStyle.Sine, Enum.EasingDirection.Out, 0, false, 0)
			local goal = {CFrame = ledgeOffset + Vector3.new(0, -2, 0) + ledgeOffset.LookVector * -1}
			local tween = TweenService:Create(ledgePart, info, goal)
			tween:Play()
			canMove = false
			playSound()

			camShake:Start()
			local dashShake = camShake:ShakeOnce(.2, 13, 0, .5)
			dashShake:StartFadeOut(.5)

			if anim == "Right" then
				grabRightAnim:Play()
			elseif anim == "Left" then
				grabLeftAnim:Play()
			end

			task.delay(.35, function()
				canMove = true
			end)
		end
	end
end

local function vaultMove(direction, anim)
	local moveRay = workspace:Raycast(head.CFrame.Position, head.CFrame.RightVector * direction + head.CFrame.LookVector * 8, raycastParams)
	if moveRay then
		if moveRay.Instance then
			vaultMoveCheck(moveRay, anim)
		end
	else
		local turnRay = workspace:Raycast(head.CFrame.Position + Vector3.new(0, -1, 0) + head.CFrame.RightVector * direction, head.CFrame.RightVector * -direction + head.CFrame.LookVector * 2, raycastParams)
		if turnRay then
			if turnRay.Instance then
				vaultMoveCheck(turnRay, anim)
			end
		end
	end
end

humanoid:GetPropertyChangedSignal("MoveDirection"):Connect(function()
	if (humanoid.MoveDirection:Dot(camera.CFrame.RightVector) > .7) and not canVault and canMove then
		vaultMove(vaultMoveNumber, "Right")
	end
	if (humanoid.MoveDirection:Dot(-camera.CFrame.RightVector) > .7) and not canVault and canMove then
		vaultMove(-vaultMoveNumber, "Left")
	end
end)

local function detectLedge(numero)
	if canVault and (humanoid:GetState() == Enum.HumanoidStateType.Freefall or humanoid:GetState() == Enum.HumanoidStateType.Running) then
		local directions = {
			Arriba = rootPart.CFrame.LookVector,
			Abajo = -rootPart.CFrame.LookVector,
		}

		local vaultCheck = workspace:Raycast(rootPart.CFrame.Position, directions[numero] * 5, raycastParams)

		if vaultCheck then
			if vaultCheck.Instance and vaultCheck.Instance.Name == "Grab" then
				local localPos = vaultCheck.Instance.CFrame:PointToObjectSpace(vaultCheck.Position)
				local localLedgePos = Vector3.new(localPos.X, vaultCheck.Instance.Size.Y / 2, localPos.Z)
				local ledgePos = vaultCheck.Instance.CFrame:PointToWorldSpace(localLedgePos)
				local ledgeOffset = CFrame.lookAt(ledgePos, ledgePos - vaultCheck.Normal)

				local magnitude = (ledgePos - head.Position).Magnitude
				if magnitude < 4 then
					canVault = false
					camShake:Start()
					local dashShake = camShake:ShakeOnce(.36, 12, 0, .5)
					dashShake:StartFadeOut(.5)

					ledgePart = Instance.new("Part")
					ledgePart.Parent = workspace
					ledgePart.Anchored = true
					ledgePart.Size = Vector3.one
					ledgePart.CFrame = ledgeOffset + Vector3.new(0, -2, 0) + ledgeOffset.LookVector * -1
					ledgePart.CanQuery = false
					ledgePart.CanCollide = false
					ledgePart.CanTouch = false
					ledgePart.Transparency = 1

					grabAnim:Play()
					playSound()

					vaultConnection = RunService.RenderStepped:Connect(function(dt)
						rootPart.Anchored = true
						humanoid.AutoRotate = false
						rootPart.CFrame = rootPart.CFrame:Lerp(CFrame.lookAt(ledgePart.Position, (ledgePart.CFrame * CFrame.new(0, 0, -1)).Position), .25)
						humanoid:ChangeState(Enum.HumanoidStateType.Seated)
					end)

					climbing = true
				end
			end
		end
	elseif not canVault then
		canVault = true
		humanoid.AutoRotate = true
		rootPart.Anchored = false
		humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
		grabAnim:Stop()

		if vaultConnection then
			vaultConnection:Disconnect()
		end

		if ledgePart then
			ledgePart:Destroy()
		end

		climbing = false
	end
end

local function climbUp()
	if climbing then	
		local climbRay = workspace:Raycast(head.CFrame.Position, head.CFrame.LookVector  * 5, raycastParams)
		if climbRay then
			print(climbRay.Instance)
			if climbRay.Instance and climbRay.Instance.Name == "Grab" then
				local localPos = climbRay.Instance.CFrame:PointToObjectSpace(climbRay.Position)
				local localLedgePos = Vector3.new(localPos.X, climbRay.Instance.Size.Y / 2, localPos.Z)
				local ledgePos = climbRay.Instance.CFrame:PointToWorldSpace(localLedgePos)
				local ledgeOffset = CFrame.lookAt(ledgePos, ledgePos - climbRay.Normal)

				local magnitude = (ledgePos - head.Position).Magnitude
				if magnitude < 4 then
					climbing = false
					canVault = true
					grabAnim:Stop()
					canMove = true
					rootPart.Anchored = false
				end
			end
		end
	end
end



UserInputService.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.Space then	
		detectLedge("Arriba")
	end

	if input.KeyCode == Enum.KeyCode.W then
		if climbing then
				climbUp()

		end
	end
end)



2 Likes