Question about viewportframes

Hi, so I had an old minimap that updated in real time and updated instantly, but caused an exponential frame drop over time. So with some help it still uses the viewportframe method, but updates with remoteevents every few seconds. So in theory it should lag less, right?

In simpler terms:
If a viewport updated every 10 seconds via remoteevent, would it still cause frame drops?

When you use remote events your sending data over the network and there is no need to do this for a minimap here is some code that can help you only update the minimap when its needed

-- LocalScript inside StarterPlayerScripts

local camera = workspace.CurrentCamera
local position = Vector3.new(0, math.huge, 0)
local updateDistance = 8

camera:GetPropertyChangedSignal("Focus"):Connect(function()
	local cameraPosition = camera.Focus.Position
	if (position - cameraPosition).Magnitude < updateDistance then return end
	position = cameraPosition
	
	print("Update Minimap")
end)

this will only update the minimap when you move more then 8 studs

and here is some infomation on ViewportFrame GUI

if possible it would be better to not adjust the camera or parts inside the viewportframe but to move the viewportframe it self like this

viewportFrame.Position = UDim2.new(0, x, 0, y)

this will prevent the viewportframe from having to render every time you move it

but a even faster method would be to save the world as a image and then use a frame and a imagelabel like this

we use GuiObject.ClipsDescendants to hide the image that is outside the frame then we can simple move the image inside the frame as the player walks around

you should be able to do this also with the viewportframe so simply replace the imagelabel with a viewportframe and move it inside the frame with ClipsDescendants set to true

3 Likes

It definitely sounds like an optimization problem. For comparison, here’s my own radar/minimap system with up to 100 entities simultaneously updating on-screen every 2nd frame (30 times per second at 60 FPS):

That’s not suggested. You’re constraining the minimap to the viewport frame’s container’s size, which will then have limited resolution and coverage.

You can perhaps show us a video demonstrating the frame drops and also show us the code snippet responsible for updating the viewport frame so we can help

What happened to the past video, that was really cool, then it switched from i assume edit : /

What you can do is shift the viewport position for let’s say 100 studs depending on how detailed you want the mini map then once you have moved more then 100 studs you update the viewport and wrap it back

That’s just complicating something that isn’t even an issue. His problem is definitely with optimization, not from the viewport frame itself

its not that complicated and I think its a good optimization to have here is a demo project of it working

minimap.rbxl (38.0 KB)

and this is the script

local camera = workspace.CurrentCamera
local frame = script.Parent

local viewportFrame = frame.ViewportFrame
for i, descendant in ipairs(workspace:GetDescendants()) do
	if descendant.ClassName == "Terrain" then continue end
	if descendant:IsA("BasePart") == false then continue end
	descendant:Clone().Parent = viewportFrame
end
local viewportCamera = Instance.new("Camera")
viewportCamera.FieldOfView = 30
viewportFrame.CurrentCamera = viewportCamera

local distance = 128
local offset = Vector3.new(0, distance * 2 / (2 * math.tan(math.rad(viewportCamera.FieldOfView) / 2)), 0)
local viewportX, viewportZ = math.huge, math.huge

camera:GetPropertyChangedSignal("Focus"):Connect(function()
	local chunkX = math.floor(camera.Focus.Position.X / distance)
	local chunkZ = math.floor(camera.Focus.Position.Z / distance)
	local x = camera.Focus.Position.X % distance / distance
	local z = camera.Focus.Position.Z % distance / distance
	if viewportX ~= chunkX or viewportZ ~= chunkZ then
		viewportX, viewportZ = chunkX, chunkZ
		local position = Vector3.new(viewportX * distance + distance / 2, 0, viewportZ * distance + distance / 2)
		viewportCamera.CFrame = CFrame.lookAt(position + offset, position, -Vector3.zAxis)
		print("Update Viewport")
	end
	viewportFrame.Position = UDim2.new(1-x, 0, 1-z, 0)
end)

changing the distance value will effect the zoom and how far the character has to walk until the mini map is updated