local function P(P,N)return math.atan2(N.X*P.Z-N.Z*P.X,N.X*P.X+N.Z*P.Z)end local function N()local N=RootCameraCreator()local X=tick()function N.Update(d)local C=tick()local r=workspace.CurrentCamera local a=PlayersService.LocalPlayer if X==nil or C-X>1 then N:ResetCameraLook()d.LastCameraTransform=nil end local D=d:GetSubjectPosition()if D and(a and r)then local N=d:GetCameraZoom()if N<=0 then N=.1 end local a=d:GetHumanoid()if X and(a and a.Torso)then local N=math.min(.1,C-X)local r=d:UpdateGamepad()d.RotateInput=d.RotateInput+r*N local D=a.Torso.CFrame.lookVector local p=P(D,d:GetCameraLook())if IsFinite(p)then d.RotateInput=Vector2.new(p,d.RotateInput.Y)end end local p=d:RotateCamera(d:GetCameraLook(),d.RotateInput)d.RotateInput=Vector2.new()r.Focus=CFrame.new(D)r.CoordinateFrame=CFrame.new(r.Focus.p-N*p,r.Focus.p)d.LastCameraTransform=r.CoordinateFrame end X=C end return N end return N
-- May return NaN or inf or -inf
-- This is a way of finding the angle between the two vectors:
local function findAngleBetweenXZVectors(vec2, vec1)
	return math.atan2(vec1.X * vec2.Z - vec1.Z * vec2.X, vec1.X * vec2.X + vec1.Z * vec2.Z)
end

local function CreateAttachCamera()
	local module = RootCameraCreator()

	local lastUpdate = tick()
	function module:Update()
		local now = tick()

		local camera = workspace.CurrentCamera
		local player = PlayersService.LocalPlayer

		if lastUpdate == nil or now - lastUpdate > 1 then
			module:ResetCameraLook()
			self.LastCameraTransform = nil
		end

		local subjectPosition = self:GetSubjectPosition()
		if subjectPosition and player and camera then
			local zoom = self:GetCameraZoom()
			if zoom <= 0 then
				zoom = 0.1
			end

			local humanoid = self:GetHumanoid()
			if lastUpdate and humanoid and humanoid.Torso then
				-- Cap out the delta to 0.1 so we don't get some crazy things when we re-resume from
				local delta = math.min(0.1, now - lastUpdate)
				local gamepadRotation = self:UpdateGamepad()
				self.RotateInput = self.RotateInput + (gamepadRotation * delta)

				local forwardVector = humanoid.Torso.CFrame.lookVector

				local y = findAngleBetweenXZVectors(forwardVector, self:GetCameraLook())
				if IsFinite(y) then
					-- Preserve vertical rotation from user input
					self.RotateInput = Vector2.new(y, self.RotateInput.Y)
				end
			end

			local newLookVector = self:RotateCamera(self:GetCameraLook(), self.RotateInput)
			self.RotateInput = Vector2.new()

			camera.Focus = CFrame.new(subjectPosition)
			camera.CoordinateFrame = CFrame.new(camera.Focus.p - (zoom * newLookVector), camera.Focus.p)
			self.LastCameraTransform = camera.CoordinateFrame
		end
		lastUpdate = now
	end

	return module
end

return CreateAttachCamera
