Is this a good way to make a ledge grab system? also how do I find the ledge?

So, I’m making a game like Blackout: Revival, and I was wondering if I was making this ledge system the correct way. also I need a way to find the ledge cause sometimes I get things like this:


code:

local plr = game.Players.LocalPlayer
local Character = plr.Character or plr.CharacterAdded:Wait()
local Head = Character:WaitForChild("Head")
local Hum = Character:FindFirstChildWhichIsA("Humanoid")
local Root = Hum.RootPart
local CA = Hum:LoadAnimation(script:WaitForChild("ClimbAnim"))
local HA = Hum:LoadAnimation(script:WaitForChild("HoldAnim"))
local TouchGui = plr:WaitForChild("PlayerGui"):FindFirstChild("TouchGui")
local UIS = game:GetService("UserInputService")

ledgeavailable = true
holding = false

function climb()
	local Vele = Instance.new("BodyVelocity",Root)
	Root.Anchored = false
	Hum.AutoRotate = true
	Vele.MaxForce = Vector3.new(1,1,1) * math.huge
	Vele.Velocity = Root.CFrame.LookVector * 10 + Vector3.new(0,30,0)
	HA:Stop() CA:Play()
	game.Debris:AddItem(Vele,.15)
	holding = false
	wait(.75)
	ledgeavailable = true
end

function AttemptGrab()
	local FrontRay = Ray.new(Root.CFrame.Position, Root.CFrame.LookVector * 3)
	local Frontpart,Frontposition = workspace:FindPartOnRay(FrontRay,Character)
	local UpRay = Ray.new(Root.CFrame.Position + Vector3.new(0,3,0),Root.CFrame.LookVector * 3)
	local Uppart,Upposition = workspace:FindPartOnRay(UpRay,Character)
	print(Frontpart,Uppart)
	if Frontpart and not Uppart then
		if ledgeavailable then
			holding = true
			ledgeavailable = false
			HA:Play()
			Root.Anchored = true
			Hum.AutoRotate = false
		end
	end
end

Hum.StateChanged:Connect(function(old,new)
	if new == Enum.HumanoidStateType.Landed then
		ledgeavailable = true
	end
end)

UIS.JumpRequest:Connect(function()
	if not holding then 
		AttemptGrab()
		return
	end 
	climb()
end)