Basically trying to get a camera to look at a part, but rotate around the part aswell.
Tried looking at Camera Manipulation but it didnt work.
So dont really know what to do / where to start here
Basically trying to get a camera to look at a part, but rotate around the part aswell.
Tried looking at Camera Manipulation but it didnt work.
So dont really know what to do / where to start here
The code below will make your camera orbit the part, just make sure it’s in a LocalScript when you’re using it.
The offset variable determines where you want the camera to be. The X value determines left/right, the Y value determines up/down, and Z determines front/back. By default, the offset is 15 studs backward from the part.
The direction variable determines which direction you want the camera to rotate per iteration. It’s a little hard to explain which axis determines which, so I will refer to the below picture to describe it.
I can further clarify anything if necessary.
--[[Variables]]--
--Services--
local RunService = game:GetService("RunService");
--Main--
local cam = workspace.CurrentCamera;
local part : Part = nil; --Assign a part here
local offset = Vector3.new(0, 0, 15); --Positional offset from the part. The Z axis is front and back.
offset = CFrame.new(offset);
local direction = Vector3.new(0, 3, 0); --This will be turned into a CFrame later. By default, this will be a simple horizontal rotation.
--[[Functions]]--
local cfAng = CFrame.Angles;
local rad = math.rad;
function radifyVector(vector : Vector3)
return cfAng(rad(vector.X), rad(vector.Y), rad(vector.Z));
end
function spin()
cam.CameraType = Enum.CameraType.Scriptable; --Makes it so we can manipulate the camera
cam.CFrame = CFrame.new(part.Position) * offset;
--OrbitingPart.CFrame = CFrame.new(PartToOrbit.Position) * CFrame.Angles(math.rad(RotStep), 0, 0)
for i = 1, 120 do
cam.CFrame = CFrame.new(part.Position) * radifyVector(direction * i) * offset;
RunService.RenderStepped:Wait();
end
end
Alright i think i get most of it, although the main things im not understanding are
Not entirely sure what this does but its returning some value
Probably just me, but when working with CFrames and stuff, why do we multiply and like not add or something
Is this better for the script if we abbreviate it or are we doing it just because
My radifyVector
function just turns a a Vector3, whose values are presumed to be angular measurements in degrees, and returns a CFrame.Angles value that uses radians.
I’m not really sure of the technical reason we multiply CFrames by each other; the article that tries to explain it is too much for my small brain to handle.
I abbreviate those two functions for readability and a small performance boost. I must emphasize that this performance boost isn’t noticable unless you are calling them a considerable amount of times per second.
Alright, i get it somewhat
And one more quick question
i tried having it also look at the part at a angle so in the i = loop i did
for i = 1, 120 do
print(3)
Cam.CFrame = CFrame.new(LookAt.Position) * FunnyNumberThingy(Vector3.new(0,.5,0) * i) * camOffset
Cam.CFrame = CFrame.new(Cam.CFrame.Position, LookAt.Position)
Rs.RenderStepped:Wait()
end
end
Mainly looking at
Cam.CFrame = CFrame.new(Cam.CFrame.Position, LookAt.Position)
Is this a good way of doing it or is there a better way i can have the camera look at the part its rotating?
Yes it does work
(Character limit)
If it ain’t broke, don’t fix it
Lmao Anyways thanks for the help i appreciate it
Roblox actually has an example-script on their docs specifically on how to do this. You can find it here.
Here’s their example script:
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 a common way of doing it using the RunService inside a localscript.
Name the script Camera and place it either in StarterPlayerScripts or StarterCharacterScripts.
Add a part to your workspace, this will be used as our focal point:
-- Services and References
local RunService = game:GetService("RunService")
local camera = workspace.CurrentCamera -- Current camera
local currentRot = 0 -- Variable for storing current rotation
-- Variables you can customize
local focusCFrame = workspace:FindFirstChild('Part').CFrame -- CFrame.new(0, 0, 0) or Your.Part.CFrame
local cameraOffset = CFrame.new(0, 12, 12) -- Camera Offset to part
local rotationSpeed = 6 -- How fast camera rotates
function rotateCamera(deltaTime: number)
-- Multiply with time between each frame to compensate for FPS variation
currentRot += rotationSpeed * deltaTime -- Add our rotationSpeed
-- Calculate new Position
local newPos = focusCFrame
* CFrame.Angles(0, math.rad(currentRot), 0) * cameraOffset
-- Apply new position and look towards our target
camera.CFrame = CFrame.new(newPos.Position, focusCFrame.Position)
end
-- The Magic
RunService.RenderStepped:Connect(function(deltaTime) -- Runs every "tick"
camera.CameraType = Enum.CameraType.Scriptable -- Make camera scriptable
rotateCamera(deltaTime)
end)
EDIT: Added deltaTime to the RenderStepped event; to compensate for different FPS values.
EDIT 2: Made sure camera is scriptable at all times and added reference to “Part” in workspace.