How would I move the local player's camera in a circle route around a model?

Hello, everyone.

How do I move the local player’s camera around a model in the center of the room? I just want it to move very smoothly like tween service, and around in a circle route around the model in the center.
Please go a bit in depth on the method if possible so I can get the help I need!

Sincerely,
-coolguyweir

1 Like

Is there any methods? Any help is appreciated

TweenService is a little annoying when doing circles.

You can instead just use a while loop, or even better use RunService | Roblox Creator Documentation to run an update loop every frame.

That page has some examples on how to use it.

In particular the last example, which shows how to move a GUI in a circle. You basically want to do the same thing but in that onRenderStep function update the workspace.CurrentCamera.CFrame instead of a Frame’s Position.

Also because you’re using CFrame you don’t actually need the trigonometry.

The basic idea is the same though: keep track of where in the circle you are (they called it currentTime, I call it angle) and use that to update your camera.

local cam = workspace.CurrentCamera
local center = workspace.SpawnLocation.Position

local SPEED = 1
local DISTANCE = 10

local angle = 0

local function UpdateCamera(timeSinceLastFrame)
	angle += timeSinceLastFrame * SPEED
	cam.CFrame = CFrame.Angles(0, angle, 0) * CFrame.new(0, 0, DISTANCE) + center
end

game:GetService("RunService"):BindToRenderStep("UpdateCamera", Enum.RenderPriority.Camera.Value + 1, UpdateCamera)
2 Likes

can you explain the update camera function with each step? In detail? I’m trying to learn how this works.

local cam = workspace.CurrentCamera
local center = workspace.SpawnLocation.Position

local SPEED = 1
local DISTANCE = 10

-- We'll change this angle every frame
local angle = 0

-- This function will be called every frame
-- BindToRenderStep will automatically call this function
-- with the length of time in seconds that the frame took.
local function UpdateCamera(timeSinceLastFrame)

	-- We increase `angle` every frame.
	-- If SPEED = 1, then `angle` will equal 1 after 1 second
	angle += timeSinceLastFrame * SPEED

	-- Now we update the camera CFrame.
	-- We start at 0,0,0 position looking straight out in the -Z axis
	cam.CFrame = 

	-- 1. We rotate around the Y axis by `angle`. Since `angle` will change
	--    every frame, this is where the constant rotation comes from
	CFrame.Angles(0, angle, 0)

	-- 2. We back up by DISTANCE amount. The front of the camera is in the -Z
	--    location (locally) so we want to go in the +Z direction
	* CFrame.new(0, 0, DISTANCE)

	-- 3. We translate everything to be happening around our pivot point
	--    instead of around 0,0,0
	+ center
end

-- Tell roblox to call our function every frame
game:GetService("RunService"):BindToRenderStep(
	"UpdateCamera", -- Give it a name in case we want to UnbindFromRenderStep later
	Enum.RenderPriority.Camera.Value + 1, -- Says "call this after roblox does all their camera updates"
	UpdateCamera -- Call this function
)
3 Likes

You also can replace workspace.CurrentCamera with a part so you can see how it’s working. Then you can experiment with deleting different parts.

Well, I used this and it worked:

local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")

local target = workspace.middleball:FindFirstChild("circle")  -- The object to rotate around
local camera = workspace.CurrentCamera
camera.CameraType = Enum.CameraType.Scriptable
local rotationAngle = Instance.new("NumberValue")
local tweenComplete = false

local cameraOffset = Vector3.new(0, 4, 18)
local rotationTime = 90  -- Time in seconds
local rotationDegrees = 360
local rotationRepeatCount = -1  -- Use -1 for infinite repeats
local lookAtTarget = true  -- Whether the camera tilts to point directly at the target

local function updateCamera()
	if not target then return end
	camera.Focus = target.CFrame
	local rotatedCFrame = CFrame.Angles(0, math.rad(rotationAngle.Value), 0)
	rotatedCFrame = CFrame.new(target.Position) * rotatedCFrame
	camera.CFrame = rotatedCFrame:ToWorldSpace(CFrame.new(cameraOffset))
	if lookAtTarget == true then
		camera.CFrame = CFrame.new(camera.CFrame.Position, target.Position)
	end
end

-- Set up and start rotation tween
local tweenInfo = TweenInfo.new(rotationTime, Enum.EasingStyle.Linear, Enum.EasingDirection.InOut, rotationRepeatCount)
local tween = TweenService:Create(rotationAngle, tweenInfo, {Value=rotationDegrees})
tween.Completed:Connect(function()
	tweenComplete = true
end)
tween:Play()

-- Update camera position while tween runs
RunService.RenderStepped:Connect(function()
	if tweenComplete == false then
		updateCamera()
	end
end)