Camera Suttering

When I run my camera script it stutters with each frame. I am not sure what else to do to prevent the stuttering from occurring and could use some guidance and an explanation on why it is doing what it is.

local UserInputService = game:GetService('UserInputService')
local RunService = game:GetService('RunService')
local CollectionService = game:GetService('CollectionService');

RunService:UnbindFromRenderStep("cameraRenderUpdate");

local player = game.Players.LocalPlayer
local mouse = player:GetMouse();
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:WaitForChild("Humanoid")

local camera = workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable

local zoomSpeed = 1
local rotateSpeed,defaultRotationSpeed = 0.175,0.1;
local minZoom = 6
local maxZoom = 16
local offsetDistance = 15
local velocityMultiplier = 8
local currentZoom = 10
local currentRotation = Vector2.new(0, 0)
local weight = 1

local maxAngularSpeed = 5

local m2RotationSpeed = .2;
local mobileRotationSpeed = .01;

local maxSpeed = 10000;
local maxDelta = 4000
local maxBlur = 10


--spring
-- 20 too slow..? 100 slow
local springConstant = 100 
local velocity = Vector3.new(0, 0, 0)
local position = camera.CFrame.Position

local angularVelocity = 0
local rotation = Vector3.new()

--

local blur = game.Lighting:FindFirstChild("FastBlur") or Instance.new("BlurEffect",game.Lighting);
blur.Size = 0;
local targetCFrame = camera.CFrame

humanoid.CameraOffset = Vector3.new(0,1,0);

local function updateWeight()
	--TODO: add weight if flash banged/time dialation slower
end
local function createTestPart(pos)
	local part = Instance.new("Part",workspace)
	part.Name = "TestPart"
	part.Size = Vector3.new(1,1,1)
	part.CFrame = pos
	part.Anchored = true
	part.BrickColor = BrickColor.new("Bright red")

	return part
end


local function singleDigitLerp(a,b,t)
	return a + (b - a) * t
end

UserInputService.InputChanged:Connect(function(input)
	if input.UserInputType == Enum.UserInputType.MouseWheel then
		currentZoom = math.clamp(currentZoom - input.Position.Z * zoomSpeed, minZoom, maxZoom)
	end
end)

--UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton2)

local lastHadAction = nil;

local lastPos;	
local lastMouseDelta = Vector2.new(mouse.X,mouse.Y)
local rayparams = RaycastParams.new();
rayparams.FilterType = Enum.RaycastFilterType.Exclude

local override = true;

local function hasNaN(cframe)
	local components = {cframe:GetComponents()}
	for _, value in ipairs(components) do
		if value ~= value then
			return true
		end
	end
	return false
end
local function computeAngularVelocity(current, target, dt)
	local axis, angle = current:ToObjectSpace(target):ToAxisAngle()
	if math.abs(angle) < 0.001 then -- dead-zone
		return Vector3.new(0, 0, 0)
	end
	angle = math.clamp(angle, -maxAngularSpeed * dt, maxAngularSpeed * dt)
	return axis * angle / dt
end


UserInputService.InputBegan:Connect(function(input)
	if input.KeyCode == Enum.KeyCode.LeftControl then
		local lockCenter = (UserInputService.MouseBehavior == Enum.MouseBehavior.LockCenter);
		UserInputService.MouseBehavior = (lockCenter) and Enum.MouseBehavior.Default or Enum.MouseBehavior.LockCenter;
		humanoid.CameraOffset = (lockCenter) and Vector3.new(0,1,0) or Vector3.new(1,1,0);
	end
end)

local touchPadVelocity;
if UserInputService.TouchEnabled then	
	local guiFrameVariable = player.PlayerGui:WaitForChild("TouchGui"):WaitForChild("TouchControlFrame"):WaitForChild("DynamicThumbstickFrame")

	local function isTouchInside(point, frame)
		local framePosition = frame.AbsolutePosition
		local frameSize = frame.AbsoluteSize

		local frameLeft = framePosition.X
		local frameRight = framePosition.X + frameSize.X
		local frameTop = framePosition.Y
		local frameBottom = framePosition.Y + frameSize.Y

		local pointX = point.X
		local pointY = point.Y

		return pointX >= frameLeft and pointX <= frameRight and pointY >= frameTop and pointY <= frameBottom
	end

	local function allPointsInGui(touchPositions)
		local bool = true;
		for i,v in pairs(touchPositions) do
			if not isTouchInside(v,guiFrameVariable) then
				bool = false;
			end
		end
		return bool;
	end

	local function diversePointsInGui(touchPositions) 
		local bools = {};
		for i,v in pairs(touchPositions) do
			table.insert(bools, isTouchInside(v,guiFrameVariable))
		end

		local last = nil
		for i,v in pairs(bools) do
			if not last then 
				v = last; 
			elseif last ~= v then
				return true;
			end
		end

		return false;
	end

	UserInputService.TouchPan:Connect(function(touchPositions, totalTranslation, velocity, state, gpe)
		if allPointsInGui(touchPositions) then
			touchPadVelocity = Vector2.new();
		elseif diversePointsInGui(touchPositions) then
			touchPadVelocity = velocity*2
		else
			touchPadVelocity = velocity;
		end
	end)
end

local function lockCharacter()
	local mousePos = UserInputService:GetMouseLocation()
	local mouseRay = camera:ScreenPointToRay(mousePos.X, mousePos.Y)
	local mouseWorldPos = mouseRay.Origin + mouseRay.Direction*50
	local lookVector = Vector3.new(mouseWorldPos.X, character.HumanoidRootPart.Position.Y, mouseWorldPos.Z) - character.HumanoidRootPart.Position
	character.HumanoidRootPart.CFrame = CFrame.lookAt(character.HumanoidRootPart.Position, lookVector + character.HumanoidRootPart.Position)
	humanoid.AutoRotate = false;
end

local check = false;
local hadBlock = false;
RunService:BindToRenderStep("run",Enum.RenderPriority.Camera.Value+1,function(dt)
	if CollectionService:HasTag(character,"Action") then
		check = true;
		lockCharacter()
		lastHadAction = tick();
	end

	if CollectionService:HasTag(character,"Blocking") then
		hadBlock = true
		lockCharacter();
	elseif hadBlock  then
		humanoid.AutoRotate = true;
		hadBlock = false;		
	end

	if lastHadAction and (tick()-lastHadAction) >= .5 and check then
		check = false;
		humanoid.AutoRotate = true;
	end

	rayparams.FilterDescendantsInstances = {character};

	updateWeight()	

	local delta = Vector2.new(UserInputService:GetMouseDelta().X, UserInputService:GetMouseDelta().Y)

	local speed = delta.Magnitude / dt
	local targetBlurSize = math.min(speed / maxDelta * maxBlur, maxBlur)
	blur.Size = singleDigitLerp(blur.Size, targetBlurSize, .1)

	if delta.X == 0 and delta.Y == 0 and not UserInputService.TouchEnabled then
		delta = Vector2.new(mouse.X, mouse.Y)-lastMouseDelta
		weight = .1;
	else
		weight = 1;
	end
	--currentRotation = currentRotation + delta * rotateSpeed * weight

	if (UserInputService.TouchEnabled and touchPadVelocity) then
		currentRotation = currentRotation + touchPadVelocity * mobileRotationSpeed;
		touchPadVelocity -= touchPadVelocity * (mobileRotationSpeed*2);
	elseif not UserInputService.TouchEnabled then
		if UserInputService:IsMouseButtonPressed(Enum.UserInputType.MouseButton2) and (UserInputService.MouseBehavior == Enum.MouseBehavior.Default or UserInputService.MouseBehavior == Enum.MouseBehavior.LockCurrentPosition) then
			UserInputService.MouseBehavior = Enum.MouseBehavior.LockCurrentPosition
			currentRotation = currentRotation + delta * m2RotationSpeed
		else
			if UserInputService.MouseBehavior == Enum.MouseBehavior.LockCurrentPosition then
				UserInputService.MouseBehavior = Enum.MouseBehavior.Default
			end
			currentRotation = currentRotation + delta * rotateSpeed * weight
		end
	end

	currentRotation = Vector2.new(currentRotation.X,math.clamp(currentRotation.Y,-60,60));

	local verticalRotation = CFrame.Angles(math.rad(currentRotation.Y), 0, 0)
	local horizontalRotation = CFrame.Angles(0, -math.rad(currentRotation.X), 0)

	local newCFrame = CFrame.new(character.PrimaryPart.Position) * horizontalRotation * verticalRotation * CFrame.new(0, 0, -currentZoom)

	local ray = workspace:Raycast(character.PrimaryPart.Position, (character.PrimaryPart.Position- newCFrame.Position).Unit*-currentZoom, rayparams);
	if ray then
		newCFrame = CFrame.new(character.PrimaryPart.Position) * horizontalRotation * verticalRotation * CFrame.new(0,0,-math.clamp((character.PrimaryPart.Position-ray.Position).Magnitude*.95,minZoom,maxZoom));
	end


	if override then
		override = false;
		targetCFrame = CFrame.new(newCFrame.Position,character.PrimaryPart.Position)
	else
		local desiredCFrame = CFrame.new(newCFrame.Position,character.PrimaryPart.Position)
		local displacement = position - desiredCFrame.Position

		local springAcceleration = -2 * math.sqrt(springConstant) * velocity - springConstant * displacement

		velocity = velocity + springAcceleration * dt

		position = position + velocity * dt

		local desiredRotation = (desiredCFrame - desiredCFrame.Position)

		local axis, angle = desiredRotation:ToAxisAngle()

		local currentLookVector = targetCFrame.LookVector
		local desiredLookVector = (character.PrimaryPart.Position - targetCFrame.Position).Unit
		local cosAngularDisplacement = currentLookVector:Dot(desiredLookVector)
		local angularDisplacement = math.acos(cosAngularDisplacement)

		local angularAcceleration = -2 * math.sqrt(100) * angularVelocity - 100 * angularDisplacement

		if angularAcceleration ~= angularAcceleration then
			print("Warning: angularAcceleration is NaN")
		else
			if angularVelocity ~= angularVelocity then
				print("Warning: angularVelocity is NaN")
			else
				angularVelocity = angularVelocity + angularAcceleration * dt
			end
		end


		local rotation = CFrame.fromAxisAngle(axis, angle + angularVelocity * dt)


		local v = CFrame.new(position + velocity * dt) * rotation;
		if not hasNaN(v) then
			targetCFrame = v;
		end
	end

	camera.CFrame = targetCFrame * CFrame.new(humanoid.CameraOffset)

	lastMouseDelta = Vector2.new(mouse.X,mouse.Y)
end)
External Media