My Wall Climb system not working

I’m Trying to code a wall climbing system

the issue is that when i go on the wall it works fine but the probleme is that i want it that once the ray isnt hitting the wall then it forces you off the wall and sometimes it moves the wall aswell.

if tried a few thing but nothing worked.

this is a clip of what happens when you wall climb: https://gyazo.com/413f4bfe5e0ac3c5c1d7ad9ae79ea943

Here is the script (its a local script inside starter pack):

-- // Services
local UIS = game:GetService('UserInputService')

-- // Variables
local plr = game.Players.LocalPlayer
local Char = plr.Character or plr.CharacterAdded:Wait()
local Root = Char:WaitForChild('HumanoidRootPart')
local Wall
local OnWall = false

-- // Tabls/Dictionnaries
local Movement = {
	MovingRight = false;
	MovingLeft = false;
	MovingUp = false;
	MovingDown = false;
}

-- for the entering and exiting of the wall climbin
UIS.InputBegan:Connect(function(key,Chatting)
	if key.KeyCode == Enum.KeyCode.G and not Chatting then
		if Wall then
			if OnWall then
				Char.HumanoidRootPart.StickOnWall:Destroy()
				OnWall = false
				Wall = nil
			else
				local StickWall = Instance.new('WeldConstraint',Root)
				StickWall.Part0 = Wall
				StickWall.Part1 = Root
				StickWall.Name = 'StickOnWall'
				OnWall = true
				
				spawn(function()
					while true do
						if OnWall then return end
						Wall = nil
						OnWall = false
						Char.HumanoidRootPart.StickOnWall:Destroy()
						for i,v in pairs(Movement) do
							v = false
						end
					end
				end)
				
				
			end
		end
	end
end)


-- movement for the wall climb
UIS.InputBegan:Connect(function(key, IsTyping)
	if key.KeyCode == Enum.KeyCode.W and not IsTyping then
		
		if OnWall == false then return end
		if Wall == nil then return end
		Movement.MovingUp = true
		Char.HumanoidRootPart.StickOnWall:Destroy()
		Char.Humanoid.AutoRotate = false
		Char.HumanoidRootPart.Anchored = true
		
		while Movement.MovingUp do
			if OnWall == false then break end
			if Wall == nil then break end
			Root.CFrame = Root.CFrame * CFrame.new(0, .675, 0)
			wait()
		end
		
elseif key.KeyCode == Enum.KeyCode.S and not IsTyping then
			
			if OnWall == false then return end
			if Wall == nil then return end
			Movement.MovingDown = true
			Char.HumanoidRootPart.StickOnWall:Destroy()
			Char.Humanoid.AutoRotate = false
			Char.HumanoidRootPart.Anchored = true
			
			while Movement.MovingDown do
				if OnWall == false then break end
				if Wall == nil then break end
				Root.CFrame = Root.CFrame * CFrame.new(0, -.675, 0)
				wait()
			end
			
			
	elseif key.KeyCode == Enum.KeyCode.A and not IsTyping then
			
			if OnWall == false then return end
			if Wall == nil then return end
			Movement.MovingLeft = true
			Char.HumanoidRootPart.StickOnWall:Destroy()
			Char.Humanoid.AutoRotate = false
			Char.HumanoidRootPart.Anchored = true
			
			while Movement.MovingLeft do
				if OnWall == false then break end
				if Wall == nil then break end
				Root.CFrame = Root.CFrame * CFrame.new(-.675, 0, 0)
				wait()
			end
			
		elseif key.KeyCode == Enum.KeyCode.D and not IsTyping then
			
			if OnWall == false then return end
			if Wall == nil then return end
			Movement.MovingRight = true
			Char.HumanoidRootPart.StickOnWall:Destroy()
			Char.Humanoid.AutoRotate = false
			Char.HumanoidRootPart.Anchored = true
			
			while Movement.MovingRight do
				if OnWall == false then break end
				if Wall == nil then break end
				Root.CFrame = Root.CFrame * CFrame.new(.675, 0, 0)
				wait()
			end
	end
end)

UIS.InputEnded:Connect(function(key)
	if key.KeyCode == Enum.KeyCode.W  then
		
		Movement.MovingUp = false
		
		if OnWall and Wall then
			Char.Humanoid.AutoRotate = true
			Char.HumanoidRootPart.Anchored = false
			local StickWall = Instance.new('WeldConstraint',Root)
			StickWall.Part0 = Wall
			StickWall.Part1 = Root
			StickWall.Name = 'StickOnWall'
		end
		
elseif key.KeyCode == Enum.KeyCode.S  then
		
		Movement.MovingDown = false
		
		if OnWall and Wall then
			Char.Humanoid.AutoRotate = true
			Char.HumanoidRootPart.Anchored = false
			local StickWall = Instance.new('WeldConstraint',Root)
			StickWall.Part0 = Wall
			StickWall.Part1 = Root
			StickWall.Name = 'StickOnWall'
		end
		
elseif key.KeyCode == Enum.KeyCode.A  then
		
		Movement.MovingLeft = false		
		
		if OnWall and Wall then
			Char.Humanoid.AutoRotate = true
			Char.HumanoidRootPart.Anchored = false
			local StickWall = Instance.new('WeldConstraint',Root)
			StickWall.Part0 = Wall
			StickWall.Part1 = Root
			StickWall.Name = 'StickOnWall'
		end
		
elseif key.KeyCode == Enum.KeyCode.D  then
	
		Movement.MovingRight = false
		
		if OnWall and Wall then
			Char.Humanoid.AutoRotate = true
			Char.HumanoidRootPart.Anchored = false
			local StickWall = Instance.new('WeldConstraint',Root)
			StickWall.Part0 = Wall
			StickWall.Part1 = Root
			StickWall.Name = 'StickOnWall'
		end
		
	end	
end)

-- casting the ray and getting the wall every second
while true do
	local r = Ray.new(Root.Position, Root.CFrame.LookVector * 5)
	local hit, pos = workspace:FindPartOnRay(r,Char)
	
	if hit then
		if hit.Name == 'Wall' then
			Wall = hit
			print(Wall)
		else
			Wall = nil
			OnWall = false
			print(Wall)
		end
	end
	
	wait(1)
end

I really appreciate anyone who helps.