How would you keep the player's velocity when they hit the ground

Hello, I am currently working on a bhop script right now for my game. When the player hits the ground, they loose all of their velocity before going to the next jump.

I’ve looked at ways to calculate the minimum velocity to move an object with friction, but I don’t know how I should implement that.
I also tried using LinearVeloctities, but those give me outcomes that I am not looking for and they limit player movement.

If any of you guys have a solution to this problem I would love to hear it.

Here is the script for the BunnyHopping for anyone that needs it:

local RunService = game:GetService("RunService")

local userInput = game:GetService("UserInputService")

local player = game:GetService("Players").LocalPlayer

local Character = player.Character or player.CharacterAdded:Wait()

local humanoid = Character:WaitForChild("Humanoid") 

local VectorForce = Instance.new("VectorForce", Character.HumanoidRootPart)
local VecAttach = Instance.new("Attachment", Character.HumanoidRootPart)

local GroundForce = Instance.new("VectorForce", Character.HumanoidRootPart)

local Sprinting = Character:FindFirstChild("Sprinting")

local Crouching = Character:FindFirstChild("Crouching")

VectorForce.Attachment0 = VecAttach

VectorForce.Force = Vector3.new(0,0,0)

VectorForce.RelativeTo = Enum.ActuatorRelativeTo.Attachment0

VectorForce.ApplyAtCenterOfMass = true

local Hopping = false

local trimping = false

humanoid.JumpHeight = 4

local function Hop()
	
	if Crouching.Value == false and Character.HumanoidRootPart.AssemblyLinearVelocity.Magnitude > 30 then

		local MoveDir = Character.HumanoidRootPart.CFrame:VectorToObjectSpace(humanoid.MoveDirection)

		VecAttach.CFrame = CFrame.lookAt(VecAttach.CFrame.LookVector * -0.0001 , Character.HumanoidRootPart.CFrame:VectorToObjectSpace(Vector3.new(0, humanoid.MoveDirection.Y,0)))
		
		if VectorForce.Force.Z > -3000 and MoveDir.Z < 0 then

			Hopping = true

			if VectorForce.Force.Z > -1200 then
				VectorForce.Force = Vector3.new(0,200,-1600)
			end

			VectorForce.Force = VectorForce.Force + Vector3.new(0,0,-100)

		elseif MoveDir.Z >= 0 then

			VectorForce.Force = Vector3.new(0,0,0)

			Hopping = false

		end	

		local Connection

		Connection = humanoid.Changed:Connect(function(Property)

			if humanoid.FloorMaterial ~= Enum.Material.Air then

				task.wait(.2)

				if humanoid.FloorMaterial ~= Enum.Material.Air then

					if trimping == false then
						Hopping = false
					else
						Hopping = true
					end

					VectorForce.Force = Vector3.new(0,0,0)

					Connection:Disconnect()

				end

			end

		end)

	end
end

local RayParams = RaycastParams.new()

RayParams.FilterType = Enum.RaycastFilterType.Blacklist

game:GetService("UserInputService").JumpRequest:Connect(function()

	RayParams.FilterDescendantsInstances = {Character}

	local GroundCheck = workspace:Raycast(Character.HumanoidRootPart.Position, Vector3.new(0,-7, 0), RayParams)

	local FrontCheck = workspace:Raycast(Character.HumanoidRootPart.Position, Character.HumanoidRootPart.CFrame.LookVector * 7, RayParams)

	if GroundCheck and Hopping and FrontCheck then

		trimping = true

		local GroundAngleX = math.abs(math.deg(math.acos(GroundCheck.Normal.X)))
		local GroundAngleZ = math.abs(math.deg(math.acos(GroundCheck.Normal.Z)))

		local FrontAngle = math.abs(math.deg(math.acos(FrontCheck.Normal.Y)))

		if ( GroundAngleX ~= 90 and GroundAngleX ~= 0 ) or ( GroundAngleZ ~= 0 and GroundAngleZ ~= 90 ) or (FrontAngle ~= 90 and FrontAngle ~= 0) then
			humanoid.JumpHeight = 1
			humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
		end

	else

		if trimping == true then
			humanoid.JumpHeight = 4
			humanoid:ChangeState(Enum.HumanoidStateType.Jumping)
		end

		trimping = false

	end


end)


humanoid.StateChanged:Connect(function(oldState, newState)
	if humanoid.MoveDirection.magnitude <= .5 then
		VectorForce.Force = Vector3.new(0,0,0)
		Hopping = false
	end
end)

-- Jumping Part

if userInput.TouchEnabled then

	local jumpButton = player:WaitForChild("PlayerGui"):WaitForChild("TouchGui"):WaitForChild("TouchControlFrame"):WaitForChild("JumpButton")

	jumpButton.MouseButton1Down:Connect(function()
		Hop()
	end)
end

userInput.InputBegan:connect(function(inputObject)
	if inputObject.KeyCode == Enum.KeyCode.Space or inputObject.KeyCode == Enum.KeyCode.ButtonA then
		Hop()
	end
end)
1 Like

Did you come up with a solution?