Why does the player lose velocity mid-air?

I’m making a knockback system, and the player loses velocity mid-air, I’m not open to use physics state or anything like that as that basically cancels all animations the humanoid is playing, and I want a animation to play mid knockback, can anyone help me?

I struggled with a similar issue where the player could stop or turn mid-jump in a low gravity environment which seemed goofy. Physics was a mess and never worked. This code takes the players initial velocity, sets them to freefall, moves them in the right direction under gravity, then hands control back to the player when landed. It might work for your needs. It unbinds keyboard movement to prevent the player stoping or changing direction mid-flight.

The code checks which movement keys are down when landed and moves the player in that direction. This is important because presses are not sensed during the jump when the keys are unbound. It keeps watching until all the movement keys have been released.

Workspace gravity is set to 5.78 in my experience to simulate moon’s gravity if you want to test it out. I am not sure if freefall will work with your animations or not. Maybe the code would work without freefall.

--
-- Prevent player turns mid-jump and stopping too soon in lower gravity
--
local UserInputService = game:GetService("UserInputService")
local ContextActionService = game:GetService("ContextActionService")

local character = script.Parent
local humanoid = character:WaitForChild("Humanoid")

humanoid:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)
humanoid:SetStateEnabled(Enum.HumanoidStateType.Climbing, false)

local jumpVertVel = 7
local gravAcc = workspace.Gravity
local deltaTime = 0.25
local jumping = false

local function jump()
	
	if humanoid.Sit == true then return end
	if jumping == true then return end
	if humanoid.FloorMaterial == Enum.Material.Air then return end
	
	local landed = false

	local initialVelocity = humanoid.RootPart.AssemblyLinearVelocity
	local initialPosition = humanoid.RootPart.Position
	
	humanoid:ChangeState(Enum.HumanoidStateType.Freefall)
	
	-- disable keyboard movement keys
	ContextActionService:BindAction("freezeMovement", function() return Enum.ContextActionResult.Sink end, false, unpack(Enum.PlayerActions:GetEnumItems()))
	
	humanoid.RootPart.AssemblyLinearVelocity = Vector3.new(initialVelocity.X, jumpVertVel, initialVelocity.Z)
	local moveToTarget = initialPosition + initialVelocity * 20
	jumping = true
	
	local Y_Velocity = jumpVertVel
	local landedCount = 0 -- require sensing ground 3 time for landing to prevent false landings
	while not landed do
		wait(deltaTime)
		
		humanoid:MoveTo(moveToTarget)
		
		Y_Velocity = Y_Velocity - gravAcc * deltaTime  
		humanoid.RootPart.AssemblyLinearVelocity = Vector3.new(initialVelocity.X, Y_Velocity, initialVelocity.Z)
		
		if humanoid.FloorMaterial ~= Enum.Material.Air then 
			landedCount = landedCount + 1
			if landedCount >= 3 then
				landed = true
			end
		end
		
		if humanoid.Sit == true then 
			landed = true 
		end
	end
	
	jumping = false
	ContextActionService:UnbindAction("freezeMovement")
	
	local allMoveButtonsReleased = false
	local wkeyreleased = false
	local dkeyreleased = false
	local skeyreleased = false
	local akeyreleased = false
	
	local lookVector
	local directionVector
	local x1, x2, z1, z2
	local angle
	
	-- movement button presses lost in ContextActionService Bind/Unbind. Move manually until all movement keys released	
	while allMoveButtonsReleased == false do
		
		if humanoid.Sit == true then return end
		
		local wkey = UserInputService:IsKeyDown(Enum.KeyCode.W)
		local skey = UserInputService:IsKeyDown(Enum.KeyCode.S)
		local akey = UserInputService:IsKeyDown(Enum.KeyCode.A)
		local dkey = UserInputService:IsKeyDown(Enum.KeyCode.D)
		local spacekey = UserInputService:IsKeyDown(Enum.KeyCode.Space)

		initialPosition = humanoid.RootPart.Position
		lookVector = game.Workspace.CurrentCamera.CFrame.LookVector
		x1 = lookVector.X
		z1 = lookVector.Z

		angle = 999
		if wkey and dkey then
			angle=45
		elseif dkey and skey then
			angle=135
		elseif skey and akey then
			angle=225
		elseif akey and wkey then
			angle=315
		elseif wkey then
			angle=0
		elseif dkey then
			angle=90
		elseif skey then
			angle=180
		elseif akey then
			angle=270
		end
		
		if angle > 900 then  -- find direction from look vector based on keys pressed
			moveToTarget = initialPosition
		else
			angle = math.rad(angle)
			x2 = x1*math.cos(angle) - z1*math.sin(angle)
			z2 = x1*math.sin(angle) + z1*math.cos(angle)
			directionVector = Vector3.new(x2, 0, z2)
			moveToTarget = initialPosition + directionVector * 100
		end
		
		humanoid:MoveTo(moveToTarget)
		
		if not wkey then wkeyreleased=true end
		if not dkey then dkeyreleased=true end
		if not skey then skeyreleased=true end
		if not akey then akeyreleased=true end
		if wkeyreleased and dkeyreleased and skeyreleased and akeyreleased then
			allMoveButtonsReleased = true
		end

		if spacekey then
			wait(0.2)  -- need a moment for player velocity to change for next jump		
			allMoveButtonsReleased = true
			jump()
		end
		
		wait(0.2) -- while loop wait
	end
end


UserInputService.JumpRequest:Connect(jump)