local function f(f,G)return math_atan2(G.X*f.Z-G.Z*f.X,G.X*f.X+G.Z*f.Z)end local function G()local G=RootCameraCreator()local m=tick()function G.Update(q)local r=tick()local c=workspace.CurrentCamera if m==nil or r-m>1 then G:ResetCameraLook()q.LastCameraTransform=nil end local R=q:GetSubjectPosition()if R and c then local G=q:GetCameraZoom()if G<=0 then G=.1 end local S=q:GetHumanoid()if m and(S and S.Torso)then local G=math_min(.1,r-m)local c=q:UpdateGamepad()q.RotateInput=q.RotateInput+c*G local R=S.Torso.CFrame.lookVector local K=f(R,q:GetCameraLook())if IsFinite(K)then q.RotateInput=Vector2_new(K,q.RotateInput.Y)end end local K=q:RotateCamera(q:GetCameraLook(),q.RotateInput)q.RotateInput=ZERO_VECTOR2 c.Focus=CFrame_new(R)local n=CFrame_new(R-G*K,R)c.CFrame=n q.LastCameraTransform=n end m=r end return G end return G
-- 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

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

		local subjectPosition = self:GetSubjectPosition()
		if subjectPosition 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 = ZERO_VECTOR2

			camera.Focus = CFrame_new(subjectPosition)
			local newCFrame = CFrame_new(subjectPosition - (zoom * newLookVector), subjectPosition)
			camera.CFrame = newCFrame
			self.LastCameraTransform = newCFrame
		end
		lastUpdate = now
	end

	return module
end

return CreateAttachCamera
