Oh ok, no worries about the late replies, here are some code snippets:
Camera Utility Module (from Crusherfire)
local CameraUtilities = {}
function CameraUtilities:GetAspectRatio(camera)
local Camera = camera or game.Workspace.CurrentCamera
return Camera.ViewportSize.X / Camera.ViewportSize.Y
end
function CameraUtilities:GetViewportCenter(camera)
local Camera = camera or game.Workspace.CurrentCamera
return Vector2.new(Camera.ViewportSize.X / 2, Camera.ViewportSize.Y / 2)
end
function CameraUtilities:FitCameraAlignedBoundingBoxToCamera(size, cameraFovDeg, aspectRatio): number
local vFov = math.rad(cameraFovDeg)
local hFov = 2 * math.atan(aspectRatio * math.tan(vFov / 2))
local boxWidth = size.X
local boxHeight = size.Y
if size.X > size.Z then
boxWidth = size.X
print("size x")
else
boxWidth = size.Z
print("size z")
end
local boxAspect = boxWidth / boxHeight
local screenAspect = aspectRatio
if boxAspect > screenAspect then
return (boxWidth / 2) / math.tan(hFov / 2)
else
return (boxHeight / 2) / math.tan(vFov / 2)
end
end
function CameraUtilities:GetCameraAlignedBoundingBox(instance, camera): (CFrame, Vector3)
local camera = camera or workspace.CurrentCamera
if not camera then
return CFrame.identity, Vector3.zero
end
local baseCFrame, size do
if instance:IsA("BasePart") then
baseCFrame, size = instance.CFrame, instance.Size
elseif instance:IsA("Model") then
baseCFrame, size = instance:GetBoundingBox()
else
return CFrame.identity, Vector3.zero
end
end
local halfSize = size * 0.5
local corners = {
Vector3.new(-halfSize.X, -halfSize.Y, -halfSize.Z),
Vector3.new(-halfSize.X, -halfSize.Y, halfSize.Z),
Vector3.new(-halfSize.X, halfSize.Y, -halfSize.Z),
Vector3.new(-halfSize.X, halfSize.Y, halfSize.Z),
Vector3.new( halfSize.X, -halfSize.Y, -halfSize.Z),
Vector3.new( halfSize.X, -halfSize.Y, halfSize.Z),
Vector3.new( halfSize.X, halfSize.Y, -halfSize.Z),
Vector3.new( halfSize.X, halfSize.Y, halfSize.Z),
}
local camCF = camera.CFrame
local minX, minY, minZ = math.huge, math.huge, math.huge
local maxX, maxY, maxZ = -math.huge, -math.huge, -math.huge
for _, cornerLocal in ipairs(corners) do
local cornerWorld = baseCFrame:PointToWorldSpace(cornerLocal)
local cornerCam = camCF:PointToObjectSpace(cornerWorld)
if cornerCam.X < minX then minX = cornerCam.X end
if cornerCam.Y < minY then minY = cornerCam.Y end
if cornerCam.Z < minZ then minZ = cornerCam.Z end
if cornerCam.X > maxX then maxX = cornerCam.X end
if cornerCam.Y > maxY then maxY = cornerCam.Y end
if cornerCam.Z > maxZ then maxZ = cornerCam.Z end
end
local minCam = Vector3.new(minX, minY, minZ)
local maxCam = Vector3.new(maxX, maxY, maxZ)
local centerCam = (minCam + maxCam) * 0.5
local extentCam = maxCam - minCam
local centerWorld = camCF:PointToWorldSpace(centerCam)
local rotationOnly = camCF - camCF.Position
local boundingBoxCF = rotationOnly + centerWorld
return boundingBoxCF, extentCam
end
return CameraUtilities
Note: In the above module I added something to change which one is the width (x or z) depending on the longest part which fixes the issue but i’ll let you decide.
if size.X > size.Z then
boxWidth = size.X
print("size x")
else
boxWidth = size.Z
print("size z")
end
Client script that handles zooming (snippet):
RequestCam:Fire("false") -- disables 2d x axis camera system
Camera.CameraType = Enum.CameraType.Scriptable
local ObjectCFrame, Size = CameraUtilitiesModule:GetCameraAlignedBoundingBox(ZoomObject, Camera)
local FieldOfView = 70
local AspectRatio = CameraUtilitiesModule:GetAspectRatio()
local PaddingInStuds = 2
local Distance = CameraUtilitiesModule:FitCameraAlignedBoundingBoxToCamera(Size, FieldOfView, AspectRatio) + PaddingInStuds
local GoalPosition = ZoomObject.Position + (ZoomObject.CFrame.LookVector * Distance)
local GoalCFrame = CFrame.lookAt(GoalPosition, ZoomObject.Position, Vector3.yAxis)
Tween(Camera, 0.8, {CFrame = GoalCFrame}) -- tween function