function OrbitalCamera.Update(f,B)local e=tick()local L=e-f.lastUpdate local N=f.UserPanningTheCamera==true local m=workspace.CurrentCamera local z=m.CFrame local x=m.Focus local Q=PlayersService.LocalPlayer local s=f:GetHumanoid()local q=m and m.CameraSubject local M=q and q:IsA("\086\101\104\105\099\108\101\083\101\097\116")local P=q and q:IsA("\083\107\097\116\101\098\111\097\114\100\080\108\097\116\102\111\114\109")if f.lastUpdate==nil or L>1 then f.lastCameraTransform=nil end if f.lastUpdate then local B=f:UpdateGamepad()if f:ShouldUseVRRotation()then f.RotateInput=f.RotateInput+f:GetVRRotationInput()else local e=math.min(.1,L)if B~=ZERO_VECTOR2 then N=true f.rotateInput=f.rotateInput+B*e end local m=0 if not(M or P)then m=m+(f.TurningLeft and-120 or 0)m=m+(f.TurningRight and 120 or 0)end if m~=0 then f.rotateInput=f.rotateInput+Vector2.new(math.rad(m*e),0)N=true end end end if N then tweenSpeed=0 f.lastUserPanCamera=tick()end local d=e-f.lastUserPanCamera<TIME_BEFORE_AUTO_ROTATE local V=f:GetSubjectPosition()if V and(Q and m)then if f.gamepadDollySpeedMultiplier~=1 then f:SetCameraToSubjectDistance(f.currentSubjectDistance*f.gamepadDollySpeedMultiplier)end local B=VRService.VREnabled x=B and f:GetVRFocus(V,L)or CFrame.new(V)local e=x.p if B and not f:IsInFirstPerson()then local B=f:GetCameraHeight()local L=V-m.CFrame.p local N=L.magnitude if N>f.currentSubjectDistance or f.rotateInput.x~=0 then local x=math.min(N,f.currentSubjectDistance)L=f:CalculateNewLookVector(L.unit*X1_Y0_Z1,Vector2.new(f.rotateInput.x,0))*x local Q=e-L local s=m.CFrame.lookVector if f.rotateInput.x~=0 then s=L end local q=Vector3.new(Q.x+s.x,Q.y,Q.z+s.z)f.RotateInput=ZERO_VECTOR2 z=CFrame.new(Q,q)+Vector3.new(0,B,0)end else f.curAzimuthRad=f.curAzimuthRad-f.rotateInput.x if f.useAzimuthLimits then f.curAzimuthRad=Util.Clamp(f.minAzimuthAbsoluteRad,f.maxAzimuthAbsoluteRad,f.curAzimuthRad)else f.curAzimuthRad=f.curAzimuthRad~=0 and math.sign(f.curAzimuthRad)*(math.abs(f.curAzimuthRad)%TAU)or 0 end f.curElevationRad=Util.Clamp(f.minElevationRad,f.maxElevationRad,f.curElevationRad+f.rotateInput.y)local B=f.currentSubjectDistance*(CFrame.fromEulerAnglesYXZ(-f.curElevationRad,f.curAzimuthRad,0)*UNIT_Z)local e=V+B z=CFrame.new(e,V)f.rotateInput=ZERO_VECTOR2 end f.lastCameraTransform=z f.lastCameraFocus=x if(M or P)and q:IsA("\066\097\115\101\080\097\114\116")then f.lastSubjectCFrame=q.CFrame else f.lastSubjectCFrame=nil end end f.lastUpdate=e return z,x end return OrbitalCamera

function OrbitalCamera:Update(dt)
	local now = tick()
	local timeDelta = (now - self.lastUpdate)
	local userPanningTheCamera = (self.UserPanningTheCamera == true)
	local camera = 	workspace.CurrentCamera
	local newCameraCFrame = camera.CFrame
	local newCameraFocus = camera.Focus
	local player = PlayersService.LocalPlayer
	local humanoid = self:GetHumanoid()
	local cameraSubject = camera and camera.CameraSubject
	local isInVehicle = cameraSubject and cameraSubject:IsA('VehicleSeat')
	local isOnASkateboard = cameraSubject and cameraSubject:IsA('SkateboardPlatform')
	
	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
				userPanningTheCamera = true
				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)
				userPanningTheCamera = true
			end
		end
	end

	-- Reset tween speed if user is panning
	if 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
	
		-- Process any dollying being done by gamepad
		-- TODO: Move this
		if self.gamepadDollySpeedMultiplier ~= 1 then
			self:SetCameraToSubjectDistance(self.currentSubjectDistance * self.gamepadDollySpeedMultiplier)
		end
		
		local VREnabled = VRService.VREnabled
		newCameraFocus = VREnabled and self:GetVRFocus(subjectPosition, timeDelta) or CFrame.new(subjectPosition)

		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 > self.currentSubjectDistance or self.rotateInput.x ~= 0 then
				local desiredDist = math.min(distToSubject, self.currentSubjectDistance)
				
				-- Note that CalculateNewLookVector is overridden from BaseCamera
				vecToSubject = self:CalculateNewLookVector(vecToSubject.unit * X1_Y0_Z1, Vector2.new(self.rotateInput.x, 0)) * 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
			-- self.RotateInput is a Vector2 of mouse movement deltas since last update
			self.curAzimuthRad = self.curAzimuthRad - self.rotateInput.x
			
			if self.useAzimuthLimits then
				self.curAzimuthRad = Util.Clamp(self.minAzimuthAbsoluteRad, self.maxAzimuthAbsoluteRad, self.curAzimuthRad)
			else
				self.curAzimuthRad = (self.curAzimuthRad ~= 0) and (math.sign(self.curAzimuthRad) * (math.abs(self.curAzimuthRad) % TAU)) or 0
			end

			self.curElevationRad = Util.Clamp(self.minElevationRad, self.maxElevationRad, self.curElevationRad + self.rotateInput.y)
			
			local cameraPosVector = self.currentSubjectDistance * ( CFrame.fromEulerAnglesYXZ( -self.curElevationRad, self.curAzimuthRad, 0 ) * UNIT_Z ) 
			local camPos = subjectPosition + cameraPosVector
			
			newCameraCFrame = CFrame.new(camPos, subjectPosition)
		
			self.rotateInput = ZERO_VECTOR2
		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

return OrbitalCamera
