How to determine when a player will collide with something in a custom jumping system

You can write your topic however you want, but you need to answer these questions:

  1. What do you want to achieve? Keep it simple and clear!
    I want my system for detecting when to end my jump to be better, because currently it often stops the player early

  2. What is the issue? Include screenshots / videos if possible!
    raycast doesn’t seem to be working very well. My jumping system sets the cframe of the humanoid rootpart because it’s too glitchy when using any of the constraints, this however means that the player clips through the ground instead of stopping like they would with a constraint.

  3. What solutions have you tried so far? Did you look for solutions on the Developer Hub?

here is my current system, the first part makes it so the player won’t clip through the ground by moving them backwards, and the second part is the actual stopping mechanism.

local RayParam = RaycastParams.new()
--1st part
		RayParam.FilterDescendantsInstances = {Character}

		local cangothereray = workspace:Raycast(Hrp.Position,CFrame.lookAt(Hrp.Position,TargetCFrame.Position).LookVector*((Hrp.Position-TargetCFrame.Position).Magnitude-0.1),RayParam)
		if cangothereray then
			TargetCFrame = CFrame.new(cangothereray.Position):Lerp(TargetCFrame,-0.3)*TargetCFrame.Rotation
		end
		
		local ray = workspace:Raycast(Hrp.Position,Hrp.CFrame.UpVector * (-1+speedm),RayParam)

--2nd part

		local torget = TargetCFrame + TargetCFrame.LookVector * ((lastposx-offsetx)*-1)
		if ray and currenttimein > 0.1 then
			ContextActionService:UnbindAction("SinkFowardMovement")
			ContextActionService:UnbindAction("SinkBackwardMovement")
			ContextActionService:UnbindAction("SinkRightMovement")
			ContextActionService:UnbindAction("SinkLeftMovement")
			iscurentlyairborne = false
			humanoid.AutoRotate  = true
			jumpcd = os.clock()
			lasthit = 0
			Hrp.Anchored = false
			endearly = true
		end

The result is that sometimes the player ends jump 1-2 studs above the ground. I wonder if there are any better ways to do this.