Flying is bugged when colliding with the ground

I wrote a flying script and it works fine until I collide with the ground.

when I collide with the ground the camera and the player shake and after going up it slowly moves even when not touching anything.
https://gyazo.com/e82b0e2e3d57a08d3fbaea86fa8d5aee

local player = game.Players.LocalPlayer
local Character = script.Parent
local Humanoid = Character:FindFirstChild("Humanoid")

local cam = workspace.CurrentCamera
local UserInputService = game:GetService("UserInputService")

local idleAnim = Character:WaitForChild("Humanoid"):LoadAnimation(script:WaitForChild("FlyIdle"))
local forwardAnim = Character:WaitForChild("Humanoid"):LoadAnimation(script:WaitForChild("FlyForward"))

local flying = false
local canFly = false

Humanoid.StateChanged:connect(function(old, new)
	if new == Enum.HumanoidStateType.Freefall then
		canFly = true
	elseif new == Enum.HumanoidStateType.Landed then
		canFly = false
	end
end)

UserInputService.InputBegan:Connect(function(key, chat)
	if chat then return end

	if key.KeyCode == Enum.KeyCode.Space and (canFly or flying) then
		if not Character or not Humanoid or not Character:IsDescendantOf(workspace) or
			Humanoid:GetState() == Enum.HumanoidStateType.Dead then
			return
		end
				
		if flying then
			Humanoid.PlatformStand = false
			Character.Animate.Disabled = false
			Character.PrimaryPart:FindFirstChild("FlightForce"):Destroy()
		elseif not flying then
			Humanoid.PlatformStand = true
			Character.Animate.Disabled = true
			for i,v in ipairs(Humanoid:GetPlayingAnimationTracks()) do
				if tostring(v.Name) == "FallAnim" or tostring(v.Name) == "JumpAnim" then
					v:Stop()
				end
			end

			local bv = Instance.new("BodyVelocity")
			bv.MaxForce = Vector3.new(math.huge, math.huge, math.huge)
			bv.Velocity = Vector3.new(0,0,0)
			bv.Name = "FlightForce"
			bv.Parent = Character.PrimaryPart
			
			Character.HumanoidRootPart.CFrame = CFrame.new(Character.HumanoidRootPart.Position, Character.HumanoidRootPart.Position +  cam.CFrame.LookVector)
		end
		flying = not flying
	end
end)

game:GetService("RunService").RenderStepped:Connect(function()
	if flying then		
		Character.HumanoidRootPart.CFrame = CFrame.new(Character.HumanoidRootPart.CFrame.Position, Character.HumanoidRootPart.CFrame.Position + cam.CFrame.LookVector)

		local movez = 0
		local movex = 0
		local movey = 0

		if UserInputService:IsKeyDown(Enum.KeyCode.W) then
			movez += 60
		end
		if UserInputService:IsKeyDown(Enum.KeyCode.A) then
			movex -= 60
		end		
		if UserInputService:IsKeyDown(Enum.KeyCode.S) then
			movez -= 60
		end	
		if UserInputService:IsKeyDown(Enum.KeyCode.D) then
			movex += 60
		end
		if UserInputService:IsKeyDown(Enum.KeyCode.E) then
			movey += 40
			movez += 40
		end
		if UserInputService:IsKeyDown(Enum.KeyCode.Q) then
			movey -= 40
			movez -= 40
		end
		
		Character.PrimaryPart:FindFirstChild("FlightForce").Velocity = Character.HumanoidRootPart.CFrame.lookVector * movez + Character.HumanoidRootPart.CFrame.rightVector * movex + Character.HumanoidRootPart.CFrame.UpVector * movey
	end
end)

you can test it yourself by putting it in Starter charcter scripts

1 Like

You are changing the CFrame of the character’s HumanoidRootPart which interpolates instead of physically rotating. Which is why whenever you physically collide with the ground, it jitters around.

So instead, you can use a BodyGyro. You can adjust it’s D and P to make it as snappy as directly changing the CFrame.