How to get the viewport frame size in studs?

Hello people, I’m trying to create a minimap myself and it is a big challenge, i want to get the size of the viewport frame in studs so i could create border snapping blips, but without the size of the minimap in studs, i simply can’t.

I know it has something to do with the distance but I’m not sure on how I would tackle that, I’m super bad at math Lol.

2 Likes

Are you simply trying to clamp the position of the blip to be inside the rectangle? In that case you don’t need to know anything about the world-space position of the blip, just clamp the coordinate to be >= 0 and <= the pixel size of the map.

1 Like

but the blips arent going to be images, they gonna parts with decals, in my opinion is more performant, im saying it by experience

and i want to know the size of the viewport in studs, not the position of the blip in the viewport

The “size” of a viewport isn’t a distance in studs, it’s an angle in degrees.

Do you mean the height of a 3D object in view of the viewport at a certain distance? Or the height of the near or far planes of the view frustrum?

I might understand better with a diagram or drawing

Sorry for the late reply, i want to know how many studs the camera can see through a certain distance and fov, im not sure if theres some formula out there

1 Like

Alright, that makes sense!

Looking at the situation from the side:

A is the location of the camera, the green segment is the map that the camera is looking at, and you want to find the distance between H1 and H2. Since the triangle (H1, A, H2) is an isosceles triangle, | (H1, H2) | is twice | (H1, B) |. We can calculate that using SOHCAHTOA since it’s a right-angle triangle:

TOA => tan(angle) = opposite/adjecent => opposite = tan(angle)/adjecent

finally, the height of the map in the view from the camera is

mapCameraHeight = 2 * math.tan(math.rad(camera.FieldOfView)) / mapDistance

math.rad because camera.FieldOfView is in degrees, 2 * because opposite is only half the height.

Please try this and let me know if it works :sweat_smile: :

3 Likes

Hey, thanks for the solution! I only had to modify it a little cuz i was having some weird bugs, but now its working perfectly, there is only a small problem.

After i finished adding the bordersnap functionaly, it was working perfectly, when the blip got far away, it would clamp to the borders, but then i decided to add rotation to the minimap camera, and it broke the bordersnap

here is footage of the problem
https://drive.google.com/file/d/1BsIjYZhumsOUb_-od1FlbLH-RPzcE_Um/view

here is the current code, its just a test

local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local HRP = character:WaitForChild("HumanoidRootPart")

local raycast2d = require(player.PlayerGui:WaitForChild("RayCast2"))

local playerCamera = workspace.CurrentCamera

local distance = 1500
local fov = 1

local minimapFrame = script.Parent.Minimap
local part = minimapFrame.Part

local testBlip = minimapFrame.Blip
local blipPosition = testBlip.Position

local minimapCamera = Instance.new("Camera")
minimapCamera.Parent = workspace

minimapCamera.FieldOfView = fov

minimapFrame.CurrentCamera = minimapCamera

local height = math.tan(math.rad(minimapCamera.FieldOfView/2)) * 2 * distance
local width = height * (minimapFrame.AbsoluteSize.X / minimapFrame.AbsoluteSize.Y)

part.Size = Vector3.new(width, 100, height)
part.Parent = workspace

local params = RaycastParams.new()
params.FilterType = Enum.RaycastFilterType.Whitelist
params.FilterDescendantsInstances = {part}

game:GetService("RunService").RenderStepped:Connect(function()
	local heading = 0
	local direction = playerCamera.CFrame.LookVector
	heading = math.atan2(direction.X, direction.Z)
	heading = math.deg(heading)
	
	part.Position = HRP.Position
	minimapCamera.CFrame = CFrame.lookAt(HRP.Position + Vector3.new(0, distance, 0), HRP.Position) * CFrame.Angles(0, 0, math.rad(-90 + heading))
	
	local blipDistanceY = (HRP.Position * Vector3.new(0, 0, 1) - blipPosition * Vector3.new(0, 0, 1)).Magnitude
	
	if blipDistanceY > height/2 - testBlip.Size.Z/2 and blipPosition.Z > HRP.Position.Z then
		local ray = raycast2d.new(Vector2.new(minimapFrame.AbsolutePosition.X, minimapFrame.AbsolutePosition.Y), Vector2.new(200, 200))
		local hit, pos = ray:Cast(script.Parent, {minimapFrame})
		ray.Visible = true
		
		print(hit, pos)
		
		testBlip.Position = Vector3.new(testBlip.Position.X, 0, HRP.Position.Z + height/2 - testBlip.Size.Z/2)
	elseif blipDistanceY > height/2 - testBlip.Size.Z/2 and blipPosition.Z < HRP.Position.Z then
		testBlip.Position = Vector3.new(testBlip.Position.X, 0, HRP.Position.Z - height/2 + testBlip.Size.Z/2)
	end
	
	local blipDistanceX = (HRP.Position * Vector3.new(1, 0, 0) - blipPosition * Vector3.new(1, 0, 0)).Magnitude
	
	if blipDistanceX > width/2 - testBlip.Size.X/2 and blipPosition.X > HRP.Position.X then
		testBlip.Position = Vector3.new(HRP.Position.X + width/2 - testBlip.Size.X/2, 0, testBlip.Position.Z)
	elseif blipDistanceX > width/2 - testBlip.Size.X/2 and blipPosition.X < HRP.Position.X then
		testBlip.Position = Vector3.new(HRP.Position.X - width/2 + testBlip.Size.X/2, 0, testBlip.Position.Z)
	end
end)

my thinking was to use some kind of 2d raycast to calculate the offset that it needs to have to clamp it right to the border

1 Like

Sorry, I don’t really understand what you want

im trying to fix a bug in the blip bordersnapping, when i rotate the camera the blip doesnt stick to the border, as seen in the video, but i think i should open another thread, you already fixed my solution, but any tips i would be glad

Oh, the video is not accessible:
image

Can you put it on youtube? It’s pretty easy, just click the + :movie_camera: button:

oh sorry, im not expert at google drive Lol, heres the link

1 Like

Oh yeah I see.

I’m not sure how to fix it though, sorry :frowning:

no problem man, you already helped a lot, thanks!

1 Like