function ClassicCamera.SetCameraMovementMode(Z,a)BaseCamera.SetCameraMovementMode(Z,a)Z.isFollowCamera=a==Enum.ComputerCameraMovementMode.Follow end function ClassicCamera.Test(a)print("\067\108\097\115\115\105\099\067\097\109\101\114\097\058\084\101\115\116\040\041")end function ClassicCamera.GetCameraSubjectOffset(a)if a:IsInFirstPerson()then return Vector3.new(0,0,0)elseif a.portraitMode then return PORTRAIT_OFFSET elseif a.isSmallTouchScreen then return MOBILE_OFFSET end return Vector3.new(0,0,0)end function ClassicCamera.Update(a)local Z=tick()local T=Z-a.lastUpdate local D=workspace.CurrentCamera local U=D.CFrame local L=D.Focus local h=nil if FFlagUserNewDefaultCameraAngle and a.resetCameraAngle then local Z=a:GetHumanoidRootPart()if Z then h=(Z.CFrame*INITIAL_CAMERA_ANGLE).lookVector else h=INITIAL_CAMERA_ANGLE.lookVector end a.resetCameraAngle=false end local g=PlayersService.LocalPlayer local V=a:GetHumanoid()local z=D.CameraSubject local G=z and z:IsA("\086\101\104\105\099\108\101\083\101\097\116")local u=z and z:IsA("\083\107\097\116\101\098\111\097\114\100\080\108\097\116\102\111\114\109")local N=V and V:GetState()==Enum.HumanoidStateType.Climbing if a.lastUpdate==nil or T>1 then a.lastCameraTransform=nil end if a.lastUpdate then local Z=a:UpdateGamepad()if a:ShouldUseVRRotation()then a.rotateInput=a.rotateInput+a:GetVRRotationInput()else local D=math.min(.1,T)if Z~=ZERO_VECTOR2 then a.rotateInput=a.rotateInput+Z*D end local U=0 if not(G or u)then U=U+(a.turningLeft and-120 or 0)U=U+(a.turningRight and 120 or 0)end if U~=0 then a.rotateInput=a.rotateInput+Vector2.new(math.rad(U*D),0)end end end if a.userPanningTheCamera then tweenSpeed=0 a.lastUserPanCamera=tick()end local q=Z-a.lastUserPanCamera<TIME_BEFORE_AUTO_ROTATE local y=a:GetSubjectPosition()if y and(g and D)then local Z=a:GetCameraToSubjectDistance()if Z<.5 then Z=.5 end if a:GetIsMouseLocked()and not a:IsInFirstPerson()then local Z=a:CalculateNewLookCFrame(h)local T=a:GetMouseLockOffset()local D=(T.X*Z.rightVector+T.Y*Z.upVector)+T.Z*Z.lookVector if Util.IsFiniteVector3(D)then y=y+D end else if not a.userPanningTheCamera and a.lastCameraTransform then local Z=a:IsInFirstPerson()if(G or u or a.isFollowCamera and N)and(a.lastUpdate and(V and V.Torso))then if Z then if a.lastSubjectCFrame and((G or u)and z:IsA("\066\097\115\101\080\097\114\116"))then local Z=-Util.GetAngleBetweenXZVectors(a.lastSubjectCFrame.lookVector,z.CFrame.lookVector)if Util.IsFinite(Z)then a.rotateInput=a.rotateInput+Vector2.new(Z,0)end tweenSpeed=0 end elseif not q then local Z=V.Torso.CFrame.lookVector if u then Z=z.CFrame.lookVector end tweenSpeed=Util.Clamp(0,tweenMaxSpeed,tweenSpeed+tweenAcceleration*T)local D=Util.Clamp(0,1,tweenSpeed*T)if a:IsInFirstPerson()and not(a.isFollowCamera and a.isClimbing)then D=1 end local U=Util.GetAngleBetweenXZVectors(Z,a:GetCameraLookVector())if Util.IsFinite(U)and math.abs(U)>.0001 then a.rotateInput=a.rotateInput+Vector2.new(U*D,0)end end elseif a.isFollowCamera and(not(Z or q)and not VRService.VREnabled)then local Z=-(a.lastCameraTransform.p-y)local D=Util.GetAngleBetweenXZVectors(Z,a:GetCameraLookVector())local U=.4 if Util.IsFinite(D)and(math.abs(D)>.0001 and math.abs(D)>U*T)then a.rotateInput=a.rotateInput+Vector2.new(D,0)end end end end if not a.isFollowCamera then local g=VRService.VREnabled if FFlagUserNewDefaultCameraAngle then if g then L=a:GetVRFocus(y,T)else L=CFrame.new(y+a:GetCameraSubjectOffset())end else L=g and a:GetVRFocus(y,T)or CFrame.new(y)end local V=L.p if g and not a:IsInFirstPerson()then local T=a:GetCameraHeight()local L=y-D.CFrame.p local h=L.magnitude if h>Z or a.rotateInput.x~=0 then local g=math.min(h,Z)L=a:CalculateNewLookVectorVR()*g local z=V-L local G=D.CFrame.lookVector if a.rotateInput.x~=0 then G=L end local u=Vector3.new(z.x+G.x,z.y,z.z+G.z)a.rotateInput=ZERO_VECTOR2 U=CFrame.new(z,u)+Vector3.new(0,T,0)end else local T=a:CalculateNewLookVector(h)a.rotateInput=ZERO_VECTOR2 U=CFrame.new(V-Z*T,V)end else local D=a:CalculateNewLookVector(h)a.rotateInput=ZERO_VECTOR2 if FFlagUserNewDefaultCameraAngle then if VRService.VREnabled then L=a:GetVRFocus(y,T)else L=CFrame.new(y+a:GetCameraSubjectOffset())end else if VRService.VREnabled then L=a:GetVRFocus(y,T)elseif a.portraitMode then L=CFrame.new(y+PORTRAIT_OFFSET)else L=CFrame.new(y)end end U=CFrame.new(L.p-Z*D,L.p)+Vector3.new(0,a:GetCameraHeight(),0)end a.lastCameraTransform=U a.lastCameraFocus=L if(G or u)and z:IsA("\066\097\115\101\080\097\114\116")then a.lastSubjectCFrame=z.CFrame else a.lastSubjectCFrame=nil end end a.lastUpdate=Z return U,L end function ClassicCamera.EnterFirstPerson(a)a.inFirstPerson=true a:UpdateMouseBehavior()end function ClassicCamera.LeaveFirstPerson(a)a.inFirstPerson=false a:UpdateMouseBehavior()end return ClassicCamera

function ClassicCamera:SetCameraMovementMode( cameraMovementMode )
	BaseCamera.SetCameraMovementMode(self,cameraMovementMode)
	self.isFollowCamera = cameraMovementMode == Enum.ComputerCameraMovementMode.Follow
end

function ClassicCamera:Test()
	print("ClassicCamera:Test()")
end

function ClassicCamera:GetCameraSubjectOffset()
	if self:IsInFirstPerson() then 
		return Vector3.new(0, 0, 0)
	elseif self.portraitMode then
		return PORTRAIT_OFFSET
	elseif self.isSmallTouchScreen then
		return MOBILE_OFFSET
	end
	return Vector3.new(0, 0, 0)
end

function ClassicCamera:Update()		
	local now = tick()
	local timeDelta = (now - self.lastUpdate)

	local camera = 	workspace.CurrentCamera
	local newCameraCFrame = camera.CFrame
	local newCameraFocus = camera.Focus
	local overrideCameraLookVector = nil
	if FFlagUserNewDefaultCameraAngle and self.resetCameraAngle then
		local rootPart = self:GetHumanoidRootPart()
		if rootPart then 
			overrideCameraLookVector = (rootPart.CFrame * INITIAL_CAMERA_ANGLE).lookVector
		else
			overrideCameraLookVector = INITIAL_CAMERA_ANGLE.lookVector
		end
		self.resetCameraAngle = false
	end
	
	local player = PlayersService.LocalPlayer
	local humanoid = self:GetHumanoid()
	local cameraSubject = camera.CameraSubject
	local isInVehicle = cameraSubject and cameraSubject:IsA('VehicleSeat')
	local isOnASkateboard = cameraSubject and cameraSubject:IsA('SkateboardPlatform')
	local isClimbing = humanoid and humanoid:GetState() == Enum.HumanoidStateType.Climbing

	if self.lastUpdate == nil or timeDelta > 1 then
		self.lastCameraTransform = nil
	end

	if self.lastUpdate then
		local gamepadRotation = self:UpdateGamepad()

		if self:ShouldUseVRRotation() then
			self.rotateInput = self.rotateInput + self:GetVRRotationInput()
		else
			-- 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, timeDelta)

			if gamepadRotation ~= ZERO_VECTOR2 then
				self.rotateInput = self.rotateInput + (gamepadRotation * delta)
			end

			local angle = 0
			if not (isInVehicle or isOnASkateboard) then
				angle = angle + (self.turningLeft and -120 or 0)
				angle = angle + (self.turningRight and 120 or 0)
			end

			if angle ~= 0 then
				self.rotateInput = self.rotateInput +  Vector2.new(math.rad(angle * delta), 0)
			end
		end
	end

	-- Reset tween speed if user is panning
	if self.userPanningTheCamera then
		tweenSpeed = 0
		self.lastUserPanCamera = tick()
	end

	local userRecentlyPannedCamera = now - self.lastUserPanCamera < TIME_BEFORE_AUTO_ROTATE
	local subjectPosition = self:GetSubjectPosition()

	if subjectPosition and player and camera then
		local zoom = self:GetCameraToSubjectDistance()
		if zoom < 0.5 then
			zoom = 0.5
		end

		if self:GetIsMouseLocked() and not self:IsInFirstPerson() then
			-- We need to use the right vector of the camera after rotation, not before
			local newLookCFrame = self:CalculateNewLookCFrame(overrideCameraLookVector)

			local offset = self:GetMouseLockOffset()
			local cameraRelativeOffset = offset.X * newLookCFrame.rightVector + offset.Y * newLookCFrame.upVector + offset.Z * newLookCFrame.lookVector

			--offset can be NAN, NAN, NAN if newLookVector has only y component
			if Util.IsFiniteVector3(cameraRelativeOffset) then
				subjectPosition = subjectPosition + cameraRelativeOffset
			end
		else
			if not self.userPanningTheCamera and self.lastCameraTransform then

				local isInFirstPerson = self:IsInFirstPerson()

				if (isInVehicle or isOnASkateboard or (self.isFollowCamera and isClimbing)) and self.lastUpdate and humanoid and humanoid.Torso then
					if isInFirstPerson then
						if self.lastSubjectCFrame and (isInVehicle or isOnASkateboard) and cameraSubject:IsA('BasePart') then
							local y = -Util.GetAngleBetweenXZVectors(self.lastSubjectCFrame.lookVector, cameraSubject.CFrame.lookVector)
							if Util.IsFinite(y) then
								self.rotateInput = self.rotateInput + Vector2.new(y, 0)
							end
							tweenSpeed = 0
						end
					elseif not userRecentlyPannedCamera then
						local forwardVector = humanoid.Torso.CFrame.lookVector
						if isOnASkateboard then
							forwardVector = cameraSubject.CFrame.lookVector
						end

						tweenSpeed = Util.Clamp(0, tweenMaxSpeed, tweenSpeed + tweenAcceleration * timeDelta)

						local percent = Util.Clamp(0, 1, tweenSpeed * timeDelta)
						if self:IsInFirstPerson() and not (self.isFollowCamera and self.isClimbing) then
							percent = 1
						end

						local y = Util.GetAngleBetweenXZVectors(forwardVector, self:GetCameraLookVector())
						if Util.IsFinite(y) and math.abs(y) > 0.0001 then
							self.rotateInput = self.rotateInput + Vector2.new(y * percent, 0)
						end
					end

				elseif self.isFollowCamera and (not (isInFirstPerson or userRecentlyPannedCamera) and not VRService.VREnabled) then
					-- Logic that was unique to the old FollowCamera module
					local lastVec = -(self.lastCameraTransform.p - subjectPosition)

					local y = Util.GetAngleBetweenXZVectors(lastVec, self:GetCameraLookVector())

					-- This cutoff is to decide if the humanoid's angle of movement,
					-- relative to the camera's look vector, is enough that
					-- we want the camera to be following them. The point is to provide
					-- a sizable dead zone to allow more precise forward movements.
					local thetaCutoff = 0.4

					-- Check for NaNs
					if Util.IsFinite(y) and math.abs(y) > 0.0001 and math.abs(y) > thetaCutoff * timeDelta then
						self.rotateInput = self.rotateInput + Vector2.new(y, 0)
					end
				end
			end
		end

		if not self.isFollowCamera then
			local VREnabled = VRService.VREnabled
			
			if FFlagUserNewDefaultCameraAngle then
				if VREnabled then
					newCameraFocus = self:GetVRFocus(subjectPosition, timeDelta)
				else
					newCameraFocus = CFrame.new(subjectPosition + self:GetCameraSubjectOffset())
				end
			else
				newCameraFocus = VREnabled and self:GetVRFocus(subjectPosition, timeDelta) or CFrame.new(subjectPosition)
			end
		
			local cameraFocusP = newCameraFocus.p
			if VREnabled and not self:IsInFirstPerson() then
				local cameraHeight = self:GetCameraHeight()
				local vecToSubject = (subjectPosition - camera.CFrame.p)
				local distToSubject = vecToSubject.magnitude

				-- Only move the camera if it exceeded a maximum distance to the subject in VR
				if distToSubject > zoom or self.rotateInput.x ~= 0 then
					local desiredDist = math.min(distToSubject, zoom)
					vecToSubject = self:CalculateNewLookVectorVR() * desiredDist
					local newPos = cameraFocusP - vecToSubject
					local desiredLookDir = camera.CFrame.lookVector
					if self.rotateInput.x ~= 0 then
						desiredLookDir = vecToSubject
					end
					local lookAt = Vector3.new(newPos.x + desiredLookDir.x, newPos.y, newPos.z + desiredLookDir.z)
					self.rotateInput = ZERO_VECTOR2

					newCameraCFrame = CFrame.new(newPos, lookAt) + Vector3.new(0, cameraHeight, 0)
				end
			else
				local newLookVector = self:CalculateNewLookVector(overrideCameraLookVector)
				self.rotateInput = ZERO_VECTOR2
				newCameraCFrame = CFrame.new(cameraFocusP - (zoom * newLookVector), cameraFocusP)
			end
		else -- is FollowCamera
			local newLookVector = self:CalculateNewLookVector(overrideCameraLookVector)
			self.rotateInput = ZERO_VECTOR2

			if FFlagUserNewDefaultCameraAngle then
				if VRService.VREnabled then
					newCameraFocus = self:GetVRFocus(subjectPosition, timeDelta)
				else
					newCameraFocus = CFrame.new(subjectPosition + self:GetCameraSubjectOffset())
				end
			else
				if VRService.VREnabled then
					newCameraFocus = self:GetVRFocus(subjectPosition, timeDelta)
				elseif self.portraitMode then
					newCameraFocus = CFrame.new(subjectPosition + PORTRAIT_OFFSET)
				else
					newCameraFocus = CFrame.new(subjectPosition)
				end
			end
			newCameraCFrame = CFrame.new(newCameraFocus.p - (zoom * newLookVector), newCameraFocus.p) + Vector3.new(0, self:GetCameraHeight(), 0)
		end

		self.lastCameraTransform = newCameraCFrame
		self.lastCameraFocus = newCameraFocus
		if (isInVehicle or isOnASkateboard) and cameraSubject:IsA('BasePart') then
			self.lastSubjectCFrame = cameraSubject.CFrame
		else
			self.lastSubjectCFrame = nil
		end
	end

	self.lastUpdate = now
	return newCameraCFrame, newCameraFocus
end

function ClassicCamera:EnterFirstPerson()
	self.inFirstPerson = true
	self:UpdateMouseBehavior()
end

function ClassicCamera:LeaveFirstPerson()
	self.inFirstPerson = false
	self:UpdateMouseBehavior()
end

return ClassicCamera
