How to make smooth holding on air skill?

I’m confused, I want to make it look like we go up and shoot projectiles and stay there until the holding skill is finished. The problem with the script I made now is maybe because it has been deprecated, namely when holding our character it will move little by little and cause a glitch effect. This is the skill.

(The Local Script)

local UIS = game:GetService("UserInputService")
local RS = game:GetService("ReplicatedStorage")
local TS = game:GetService("TweenService")

local Player = game.Players.LocalPlayer
local Char
local HumRP
local Humanoid
local part

local Tool = script.Parent

local Equipped = script:WaitForChild("Equipped")
local Holding = script:WaitForChild("Holding")
local Using = script:WaitForChild("Using")
local isHolding = false

local Remotes = RS:WaitForChild("Remotes")
local Modules = RS:WaitForChild("Modules")

local SkillsHandler = script.RemoteEvent

local Mouse = require(Modules.Mouse2) 

local Animations

-- FUNCTIONS --
Tool.Equipped:Connect(function()
	SkillsHandler:FireServer("Equip")

	Char = Tool.Parent
	HumRP = Char:WaitForChild("HumanoidRootPart")
	Humanoid = Char:WaitForChild("Humanoid")

	Animations = {
		["Z"] = Humanoid:LoadAnimation(script.Animations.Z),
		["X"] = Humanoid:LoadAnimation(script.Animations.X),
		["C"] = Humanoid:LoadAnimation(script.Animations.C),
		["V"] = Humanoid:LoadAnimation(script.Animations.V),
	}
end)

Tool.Unequipped:Connect(function()
	SkillsHandler:FireServer("Unequip")
end)

UIS.InputBegan:Connect(function(Input, isTyping)
	if isTyping then return end
	if Input.KeyCode == Enum.KeyCode.V then
		if Equipped.Value and Holding.Value == "None" and not Using.Value then
			part = script.RemoteFunction:InvokeServer("GetVPart")
			if part then
				SkillsHandler:FireServer("Hold", "V", part)
			end
		end
	end
end)

UIS.InputEnded:Connect(function(Input, isTyping)
	if Input.KeyCode == Enum.KeyCode.V then
		if Holding.Value == "V" then
			isHolding = false
			SkillsHandler:FireServer("V")
		end
	end
end)

Holding:GetPropertyChangedSignal("Value"):Connect(function()
	if Holding.Value ~= "None" then
		HumRP.Anchored = true
		isHolding = true

		if Holding.Value == "V" then
			HumRP.Anchored = false
			task.wait(0.2)
			if isHolding == true then
				Animations.V:Play()
			else
				--HumRP.Anchored = false 
				Humanoid.WalkSpeed = 16
				Humanoid.JumpPower = 32
				return
			end
			repeat
				HumRP.CFrame = CFrame.lookAt(HumRP.Position, Mouse:GetHit().Position)
				if part then
					part.Position = Mouse:GetHit().Position
				end
				task.wait()
			until Holding.Value ~= "V"
			Animations.V:Stop()
		end
	else
		HumRP.Anchored = false
	end
end)

(The Script, I just skip to that part)


			elseif Variable3 == "V" then
				if vDebounce then return end
				Holding.Value = Variable3

				Using.Value = true
				vDebounce = true

				if not Holding.Value == Variable3 then
					Using.Value = false
					vDebounce = false
					return
				end

				local Damage = vDamage

				local caster = fastCast.new()

				local hasHit = false
				local start = false

				local BP = Instance.new("BodyPosition")
				BP.Name = "AirUp"
				BP.MaxForce = Vector3.new(4e4,4e4,4e4)
				BP.Position = (pHumRP.CFrame * CFrame.new(0, 18, 0)).Position
				BP.P = 4e4
				BP.Parent = pHumRP

maybe it’s because of the deprecated body position but it still works with the drawbacks I mentioned earlier and I don’t understand how to use Align Orientation