How do viewportframes work?

Hello, this is my first time using viewportframes and i want to ask some basic questions. I have this viewport and i want it to display a model. I set a part named root that is the models exact center and made the viewport that position. This is my code:

local template = script.Parent.Parent.Template:Clone() -- the viewport
	local Info = string.split(info, " ")
	template.Parent = game.Players.LocalPlayer.PlayerGui.ScreenGui
	
	local part = game.Workspace.ImageInfo:FindFirstChild(Info[1]):Clone()
	part.Parent = workspace
	
	local viewportCamera = Instance.new("Camera")
	template.CurrentCamera = viewportCamera
	viewportCamera.Parent = template

	viewportCamera.CFrame = CFrame.new(Vector3.new(0, 2, 12), part:FindFirstChild("Root").Position)

however it only displays this from the code:
image

one thing I’m thinking is it’s displaying the root part which is about vector3.new(0.01,0.01,0.01) which would be to small to appear visible. If that’s the case how would i display a model with viewport if i cant get the models position?

1 Like

The part/model you want to render inside a viewport must be parented to that viewport.
change

local part = game.Workspace.ImageInfo:FindFirstChild(Info[1]):Clone()
part.Parent = workspace

to

local part = game.Workspace.ImageInfo:FindFirstChild(Info[1]):Clone()
part.Parent = template


still the same…

I’m thinking it’s displaying the root part which is about vector3.new(0.01,0.01,0.01) which would be too small to appear visible. If that’s the case how would I display a model with viewport if I cant get the models position?

well your models have different sizes right?
edit:

viewportCamera.CFrame = CFrame.new(part:FindFirstChild("Root").Position + Vector3.new(0, 2, 12), part:FindFirstChild("Root").Position)

yes but the part of the code

viewportCamera.CFrame = CFrame.new(Vector3.new(0, 2, 12), part:FindFirstChild("Root").Position)

calls for a position which models don’t have
(I’m going off documentation… I have no idea how viewport works. maybe using position is just to get a size? even if that’s the case I can’t get the size of a model)

Model:GetBoundingBox() gives a cf and a size

local cf, size = Model:GetBoundingBox()

so like:

local cf, size = part:GetBoundingBox()
	viewportCamera.CFrame = CFrame.new(size, part:FindFirstChild("Root").Position)

(Doesn’t work)

The first argument to CFrame.new() should be a position and not a size, so this should work

viewportCamera.CFrame = CFrame.new(part:FindFirstChild("Root").Position, Vector3.new(0, 2, 12))

You will need to modify the second parameter to adapt it to best show the model

It works but may i ask what i am looking at?
image

That all depends on the correct positioning of the camera and as i said you will need to modify the second parameter to best frame the model, You will basically need to move the camera a bit behind the model’s position

i have 138 models I wont be able to correctly position the camera for all 138 models without making my code
A. look dog trash
and
B. take me like 9 hours

is there a way to automate this system

example: use

	local cf, size = part:GetBoundingBox()

You can calculate the distance of which the camera should be moved behind/up/down based on the model’s size

should i preform my calculations on the size or the position using the models size?

The first parameter to CFrame.new() will position the camera exactly at the center of the model/part so you will definitely need to move the camera behind (using the second parameter which is a lookAt Vector3) of half the model’s X size (if the camera frames the part from the X axis, if it frames the part form the Z axis you will need to move the camera behind of half the model’s Z size) but that will put it very near the model so you will need to add a bit more studs

Hey a lot of this looks good but i am having some trouble with things that are taller not fitting in the frame

just calculate the correct distance needed

local offset = Vector3.new(2, 2, 0)

local cf, size = part:GetBoundingBox()

local sizeX, sizeY, sizeZ = size.X, size.Y, size.Z

local halfFov = math.rad(viewportCamera.FieldOfView * 0.5)
local halfSize = math.max(sizeX, sizeY) * 0.5

local dist = (halfSize) / math.tan(halfFov) + (sizeZ * 0.5)

viewportCamera.CFrame = CFrame.new((cf * CFrame.new(Vector3.zAxis * dist + offset)).Position , cf.Position)
3 Likes

Okay, thanks. I’m being honest I don’t know what half of your math is but it works so thanks for saving me 9 hours of work and trash looking code

its using trigonometry to calculate the distance(b in the pick) using the fov(beta in pic) and size(c * 2 in pic)
image

1 Like

is there a way to automate this system

Here’s a one-liner I frequently use, doesn’t even require a camera.

local Size = Model:GetExtentsSize()
Model:PivotTo(CFrame.new(0, 0, -math.max(Size.X, Size.Y, Size.Z)) * CFrame.Angles(0, math.pi, 0))
2 Likes