How can I move the character smoothly and get accurate results?

Hi DevForum,

I’m trying to make the character move in an arc like motion, and then hit the ground in the end result, something like this sketch:

Please do take into account that I’m using a Runservice.Heartbeat loop to move the character and raycasting to detect how far the player is from the ground. Also, the character should be able to move where they’re looking in the air, which I didn’t have a problem with.

That being said, I would use bezier curves, but since the end destination could always be changing, I scrapped that idea. I tried using bodyvelocity to constantly change the velocity, and came up with this:

The movement is smooth and I was able to constantly move in the direction I was looking, but the end result is somewhat inaccurate and the character ends up flinging.

I then tried using a projectile motion approach to where I manually moved the character’s CFrame/Position, and came up with this:

Code:
local RunService = game:GetService("RunService")
local RS = game:GetService("ReplicatedStorage")

--// Objects
local testpart = workspace.TestPart


--// Data


--// Event Handlers
RS.RemoteEvent.OnServerEvent:Connect(function(player, data)
	local character = data.Character
	
	if character then
		local hrp = character.HumanoidRootPart
		
		local yinitialSpeed = 100

		local ySpeed = yinitialSpeed
		local xSpeed = 90
		local gravityRate = 10
		local gravityExponentIncrease = 3
		local intervalTime = 0.125
	
		local connection

		connection = RunService.Heartbeat:Connect(function(dT)
			local rayOrigin = hrp.Position
			local rayDirection = rayOrigin - Vector3.new(0, 10, 0)

			local raycastParams = RaycastParams.new()
			raycastParams.FilterType = Enum.RaycastFilterType.Include
			raycastParams.FilterDescendantsInstances = {workspace.Map}
			
			if ySpeed <= 0 then
				local raycastResult = workspace:Raycast(rayOrigin, rayDirection, raycastParams)

				if raycastResult then
					connection:Disconnect()

					print("Found Result: ".. raycastResult.Instance.Name.. " at position: ".. tostring(raycastResult.Position))
--					testpart.CanCollide = true
--					bodyVelocity:Destroy()
					
					
					local hb = Instance.new("Part")
					hb.Anchored = true
					hb.CanCollide = false
					hb.Color = Color3.fromRGB(255,0,0)
					hb.Size = Vector3.new(15,10,15)
					hb.Material = Enum.Material.ForceField
					hb.Position = hrp.Position
					hb.Parent = workspace
					
					wait(1)
					
					hrp.Anchored = false
					
					print("Set!")
				else
					print("Looking for result...")
				end
			end
			
			local xVelocity = hrp.CFrame.LookVector * xSpeed
			local yVelocity = hrp.CFrame.UpVector * ySpeed

			hrp.Position = hrp.Position + (xVelocity * dT) + (yVelocity * dT)
--			testPath(testpart)


			if ySpeed <= 0 then
				gravityRate += gravityExponentIncrease * (dT / intervalTime)
			end

			ySpeed -= gravityRate * (dT / intervalTime)

		end)
	end
end)

As you can see, the movement is jittery and snappy, as well as the fact that you can’t change direction mid arc, but the end result of the position is accurate and there is no flinging.

I was wondering if anyone can recommend a method to where I can have both smooth movement and accurate end position results, help would greatly be appreciated!