Decided to think out of the box and make a spinner, put put it into ReplicatedStorage, and then the client could then clone it then, parent it to workspace. Then, after each RenderStep, it would set the camera’s CFrame to a part welded to the spinner, with whatever offset I want.
Interesting solution, but there is a simpler solution using pure CFrames.
local RunService = game:GetService('RunService')
local ReplicatedStorage = game:GetService('ReplicatedStorage')
local localCharacter = game.Players.LocalPlayer.Character or game.Players.LocalPlayer.CharacterAdded:Wait()
repeat wait() until localCharacter:FindFirstChild('Head')
local camera = workspace:WaitForChild('Camera')
camera.CameraType = Enum.CameraType.Scriptable
camera.CFrame = CFrame.new() * CFrame.Angles(0, 0, 0)
Instance.new('BlurEffect', camera)
local centerCFrame = CFrame.new(0,20,0) -- center of the rotation
local offsetCFrame = CFrame.new(0,0,50) -- 50 stud radius (moves it backwards)
local currentAngle = 0 -- in degrees
function rotateCamera()
camera.CFrame = centerCFrame*CFrame.Angles(0,math.rad(currentAngle),0)*offsetCFrame
currentAngle = currentAngle + 1
end
RunService:BindToRenderStep('CameraRotation', Enum.RenderPriority.Camera.Value + 1, rotateCamera)
EDIT: Better explanation.
Using CFrames, I first move the camera to the center position. I then rotate it x amount of degrees. Finally, I move it backwards 50 studs. If you want the camera to look down, you would add another CFrame.Angles at the end with a rotation to make it look down a bit.