Buggy wall climbing system

I have a wall climbing system that is working quite perfectly except for one part.

I am trying to apply this mechanism:

and it detects it correctly but pretty buggy, here is a video to see what I mean:

here is the code:

function WallClimb:GetClimbCFrame(raycastResult)
	local lookVector, rightVector, upVector, position

	local isBelowAnyBall = false
	for _, ball in ipairs(Balls:GetChildren()) do
		if raycastResult.Position.Y < (ball.Position.Y - 5) then
			isBelowAnyBall = true
		end
	end

	if isBelowAnyBall then
		self.IsBelow = true
		lookVector = self.Super.HumanoidRootPart.CFrame.LookVector
	else
		self.IsBelow = false
		lookVector = raycastResult.Normal * -1
	end

	rightVector = lookVector:Cross(Vector3.yAxis).Unit
	upVector = rightVector:Cross(lookVector).Unit
	position = raycastResult.Position + (raycastResult.Normal * self.HoldDistanceFromWall)

	return CFrame.fromMatrix(position, rightVector, upVector)
end

function WallClimb:GetMoveVector(cframe, raycastResult)
	local normalCFrame = cframe * CFrame.Angles(math.pi / -2, 0, 0)

	local moveDirection = self.Super.Humanoid.MoveDirection

	local relativeMoveDirection = workspace.CurrentCamera.CFrame.Rotation:PointToObjectSpace(moveDirection)
	relativeMoveDirection *= Vector3.new(1, 0, -1)

	if relativeMoveDirection.Magnitude > 0 then
		relativeMoveDirection = relativeMoveDirection.Unit
	end

	local moveVector = normalCFrame.Rotation:PointToWorldSpace(relativeMoveDirection)

	return moveVector
end

function WallClimb:StartClimbing(raycastResult, headRaycastResult, deltaTime)
	local isBelowAnyBall = false
	for _, ball in ipairs(Balls:GetChildren()) do
		if raycastResult.Position.Y < (ball.Position.Y - 5) then
			isBelowAnyBall = true
			break
		end
	end

	if isBelowAnyBall then
		self.PlayingAnimation:Stop()
		if self.PlayingAnimation ~= self.ClimbingAnimation2 then
			self.PlayingAnimation = self.ClimbingAnimation2
			self.PlayingAnimation:Play()
		end
	else
		self.PlayingAnimation:Stop()
		if self.PlayingAnimation ~= self.ClimbingAnimation then
			self.PlayingAnimation = self.ClimbingAnimation
			self.PlayingAnimation:Play()
		end
	end

	if not self.IsClimbing then
		self.IsClimbing = true
	end

	local framerate = 60
	local timeMultiplier = deltaTime * framerate

	local cframe = raycastResult and self:GetClimbCFrame(raycastResult) or self.CFrame
	local moveVector = self:GetMoveVector(cframe, raycastResult)

	self.CFrame = cframe
	self.CFrame += moveVector * self.ClimbSpeed * deltaTime
	self.Super.HumanoidRootPart.Anchored = true

	if self.IsBelow and headRaycastResult then
		cframe = self:GetClimbCFrame(headRaycastResult)
		moveVector = self:GetMoveVector(cframe, headRaycastResult)
	end

	self.PlayingAnimation:AdjustSpeed(moveVector.Magnitude * self.AnimationSpeed)
	self.Super.HumanoidRootPart.CFrame = self.Super.HumanoidRootPart.CFrame:Lerp(self.CFrame, self.MoveLerp * timeMultiplier)
end

I would apperciate the help!

Is it running on while wait? heartbeat? … ?

also i wouldnt trust raycasts for these things.

raycasts are known to be buggy

image

Yes it is

But i see in the video it works great. what are you trying to achieve?

when you climb to the lowest part, it slides you and then stops working, repeat the video and you will notice (Time: 0:05)

So that must be issue with gravity.

on a LOCAL script set the gravity to 0 while it climbs and set it back to normal when it stops climbing,

Well, it didn’t affect the system in any way