But then on other resolutions, mostly box shaped ones, some parts can be only partially visible or not visible at all

I can get the resolution from Camera.ViewportSize, and maybe I could increase the FOV or raise the camera position depending on certain aspect ratios, but maybe there’s a better solution out there.

I’m assuming you’re gonna make a tile based game, so why don’t you just make the tiles disappear when they’re too far from the player? Also I don’t recommend you mess with FOV too much cause it starts to look bad.

The tiles were more of an example so you could tell that parts are off screen, but making parts disappear is the opposite of what I want, I’m trying to get every device to see all the parts, not some devices missing parts.

If I were you, I would move the camera farther away until all the parts fit. The only other solution I could think of is changing the shape of the subject, like making your parts fill a square.

I think this is a step in the right direction, but I’m confused about what the boxheight and boxwidth are, is that just the Y and X or Z of the entire grid? Doing that right now returns a very small negative number, so I think I got that wrong. Also, what would I do with the distanceAbove? Do I just add it to the Y of the camera position?

I guess this problem is a bit more complicated than I thought

The easiest way I can think of would be to find which size is bigger and use that as the “primary” side

local diagAngle = math.rad(Camera.DiagonalFieldOfView/2)
local distance
if width > height then
distance = width * math.tan(diagAngle)/math.cos(diagAngle)
else
distance = height/math.cos(diagAngle)
end

This is a similar approach but it doesnt mistakenly assume that the ratio between the height and width is the exact same as the cameras

If you want to rotate it just swap height and width and rotate the cframe

local Camera = workspace.CurrentCamera
local width = workspace.PlayingField.Size.Z
local height = workspace.PlayingField.Size.X
local diagAngle = math.rad(Camera.DiagonalFieldOfView/2)
local distanceAbove
if width > height then
distanceAbove = width * math.tan(diagAngle)/math.cos(diagAngle)
else
distanceAbove = height/math.cos(diagAngle)
end
workspace.CurrentCamera.CameraType = Enum.CameraType.Scriptable
workspace.CurrentCamera.CFrame = CFrame.new(workspace.PlayingField.Position + Vector3.new(0, distanceAbove, 0), workspace.PlayingField.Position)

Sorry I got a bit confused, sorry for wasting your time trying a bunch of bad code

local Camera = workspace.CurrentCamera
local width = workspace.PlayingField.Size.Z
local height = workspace.PlayingField.Size.X
local diagFov = math.rad(Camera.DiagonalFieldOfView/2)
local distanceAbove
local diagAngle = math.atan(Camera.ViewportSize.Y/Camera.ViewportSize.X)
if width > height then
distanceAbove = width * math.tan(diagFov)/math.cos(diagAngle)
else
distanceAbove = height * math.tan(diagFov)/math.sin(diagAngle)
end
workspace.CurrentCamera.CameraType = Enum.CameraType.Scriptable
workspace.CurrentCamera.CFrame = CFrame.new(workspace.PlayingField.Position + Vector3.new(0, distanceAbove, 0), workspace.PlayingField.Position)