Adjusting Camera View to Dynamically Fit Two Parts in Roblox

Hello,

I’m currently working on a project and I need help with my camera system. Here’s the problem I’m facing:

I have two parts, Part A and Part B. I’m trying to create a camera system that always fits these two parts in view, with the camera focusing on the center point between them. I have tried several different ways to calculate the camera’s position to ensure that both parts are always visible in the viewport, but the camera appears too zoomed out or zoomed in; it never perfectly fits the screen.

Here’s the code I have been using to position the camera:

local Camera = workspace.CurrentCamera
local PartA = workspace.Part1
local PartB = workspace.Part2

local PartA_Position = PartA.Position
local PartB_Position = PartB.Position

local Distance = (PartA_Position - PartB_Position).Magnitude
local Mid_Point = PartA_Position:Lerp(PartB_Position, 0.5)
local Result= CFrame.new(Mid_Point, PartA_Position) * CFrame.Angles(0, math.rad(90), 0)
Result*= CFrame.new(0, 0, -Distance)
		
Camera.Cframe = Result

I’m really bad at math so this is the best I could do that makes sense to me. So ideally the only object that should be updated or changed to make the parts fit is the Camera, not the parts themselves. I’m aware that there’s FOV for the camera and ViewportSize too, but I have tried experimenting with those values and tried to come up with formulas to update the camera’s cframe but failed and couldn’t come up with anything.

So to better visualize, this is what I would want the goal to look like:

Any help would be appreciated. Thank you in advance!

You can adjust the FOV of the camera based on the distance between the two parts, you would go about doing it like this:

local Camera = workspace.CurrentCamera
local PartA = workspace.Part1
local PartB = workspace.Part2

local PartA_Position = PartA.Position
local PartB_Position = PartB.Position

local Distance = (PartA_Position - PartB_Position).Magnitude
local Mid_Point = PartA_Position:Lerp(PartB_Position, 0.5)

local FOV = math.deg(2 * math.atan(Camera.ViewportSize.X / (2 * Distance)))

Camera.CFrame = CFrame.new(Mid_Point)
Camera.FieldOfView = FOV

Know that this code assumes that the camera’s AspectRatio is set correctly and remains constant. If the AspectRatio changes, you may need to update the calculation accordingly x

Hey, thanks for the reply. I tried setting the FOV as you instructed and I wasn’t able to get the results I wanted. The parts(A and B) are not even visible on the screen.

We can try a different approach, instead of adjusting the FOV we can adjust the camera’s position and orientation to ensure both parts are visible on the screen, try this one and let me know if it works or not :stuck_out_tongue:

local Camera = workspace.CurrentCamera
local PartA = workspace.Part1
local PartB = workspace.Part2

local PartA_Position = PartA.Position
local PartB_Position = PartB.Position

local Distance = (PartA_Position - PartB_Position).Magnitude
local Mid_Point = PartA_Position:Lerp(PartB_Position, 0.5)
local LookVector = (PartA_Position - PartB_Position).Unit
local UpVector = Vector3.new(0, 1, 0)

local CameraDistance = Distance / (2 * math.tan(math.rad(Camera.FieldOfView / 2)))

local CameraPosition = Mid_Point - (LookVector * CameraDistance)

Camera.CFrame = CFrame.new(CameraPosition, Mid_Point, UpVector)
Camera:LookAt(Mid_Point)

I tried the new code u provided and it seems like Camera:LookAt() is not a method for Camera. I commented that line out just in case an ran the code and still got no good results. It’s even more zoomed out and close to the position of (0, 0, 0) for some reason.

So sorry omg I accidentally made a mistake, LookAt is not available for the Camera object, we can manually calculate the rotation of the camera using LookVector and UpVector to set the Camera.CFrame properly, here is how you would go about doing that:

local Camera = workspace.CurrentCamera
local PartA = workspace.Part1
local PartB = workspace.Part2

local PartA_Position = PartA.Position
local PartB_Position = PartB.Position

local Distance = (PartA_Position - PartB_Position).Magnitude
local Mid_Point = PartA_Position:Lerp(PartB_Position, 0.5)
local LookVector = (PartB_Position - PartA_Position).Unit
local UpVector = Vector3.new(0, 1, 0)

local CameraDistance = Distance / (2 * math.tan(math.rad(Camera.FieldOfView / 2)))

local CameraPosition = Mid_Point - (LookVector * CameraDistance)
local CameraRotation = CFrame.new(Vector3.new(), LookVector, UpVector)

Camera.CFrame = CameraPosition * CameraRotation