Don't understand ToWorldSpace in this developer page tutorial

Hi! I just read a tutorial within camera manipulation on the developer page, it talked about making cameras rotate around a specific part. I understood all the materials present in the article, except this one line regarding ToWorldSpace. If someone could explain that to me I’d be very grateful, thanks!

Code (line 21):

local TweenService = game:GetService("TweenService")
local RunService = game:GetService("RunService")
 
local target = workspace:FindFirstChild("Part")  -- 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, 10, 12)
local rotationTime = 15  -- 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)

Here’s the link to the article page itself.


So it’s just doing

camera.CFrame = rotatedCFrame * CFrame.new(cameraOffset)

Where cameraOffset is a Vector3. If you still can’t understand:

Imagine an arrow in 3D space. It is pointing in a random direction. Now, let’s say that you want to get the position on the top of the arrow. You would do something like local = arrow.CFrame * CFrame.new(0, 1, 0), which will give you a position that’s always on the top of the arrow no matter the direction it’s pointing at. This is different from CFrame + Vector3, which applies the offset in worldspace, whereas CFrame * CFrame applies the offset in objectspace relative to the first CFrame.