Laggy viewport frames problem

Hello!
I am currently making a space game, with visible planets, that are made out of Viewport Frames, inside a Billboard Gui, which is inside a ScreenGui. A script inside is calculating the planet’s position relative to player’s current position and updating everything using RenderStepped event. The problem is, that when I set my graphics quality to minimum, everything gets very laggy. Im pretty sure RenderStepped event slowed down by a lot.
Here is an example video, of the problem:

Any ideas on how could I fix the lag, and make my game playable?
Thanks for help!

2 Likes

Since you’re in Help and Feedback > Scripting Support, mind showing the problematic code? I tested on my end (in studio and on the client), and I don’t have this issue.

Maybe you can change your Frame Rate Limit, maybe its works?

Alright, here is my code:

local player = game.Players.LocalPlayer
local camera = game.Workspace.CurrentCamera
local model = script.Parent
local planets = game.Workspace.Planets
local covermindistance = 10000
local newcamera = Instance.new("Camera")
newcamera.Parent = model
for i,v in pairs(model:GetChildren()) do
	if v:IsA("ViewportFrame") then
		v.CurrentCamera = newcamera
	end
end

local campart = Instance.new("Part")
campart.Anchored = true
campart.Transparency = 1
campart.CanCollide = false
campart.Parent = newcamera

model.Adornee = campart

model.Size = UDim2.new(0,camera.ViewportSize.X,0,camera.ViewportSize.Y)
camera:GetPropertyChangedSignal("ViewportSize"):Connect(function()
	model.Size = UDim2.new(0,camera.ViewportSize.X,0,camera.ViewportSize.Y)
end)


game:GetService("RunService").RenderStepped:Connect(function()
	-- example body
	local distance = (camera.CFrame.Position-planets.ExampleBody.CenterPos.Value).Magnitude
	if distance<0 then
		distance = -distance
	end
	if distance > covermindistance then -- check if camera is far away enough
		model.ExampleBody.Visible = true
		local pos = planets.ExampleBody.CenterPos.Value:Lerp(camera.CFrame.Position, 0.8)
		model.ExampleBody.Part.Position = pos -- set position of the part in the viewport frame
	else
		model.ExampleBody.Visible = false
	end
	-- Camera
	newcamera.CFrame = camera.CFrame
	campart.CFrame = newcamera.CFrame*CFrame.new(0,0,-500)
	newcamera.FieldOfView = camera.FieldOfView
end)

I can change my Frame Rate Limit to a higher one. But users on weaker devices won’t really be able to. I need to fix this, mainly for people who don’t max out their graphics.

İ will try to fix this very soon :slight_smile:

local player = game.Players.LocalPlayer
local camera = game.Workspace.CurrentCamera
local model = script.Parent
local planets = game.Workspace.Planets
local covermindistance = 10000
local newcamera = Instance.new("Camera")
newcamera.Parent = model
for i,v in pairs(model:GetChildren()) do
	if v:IsA("ViewportFrame") then
		v.CurrentCamera = newcamera
	end
end

local campart = Instance.new("Part")
campart.Anchored = true
campart.Transparency = 1
campart.CanCollide = false
campart.Parent = newcamera

model.Adornee = campart

model.Size = UDim2.new(0,camera.ViewportSize.X,0,camera.ViewportSize.Y)
camera:GetPropertyChangedSignal("ViewportSize"):Connect(function()
	model.Size = UDim2.new(0,camera.ViewportSize.X,0,camera.ViewportSize.Y)
end)


game:GetService("RunService").RenderStepped:Connect(function()
	-- example body
	local distance = (camera.CFrame.Position-planets.ExampleBody.CenterPos.Value).Magnitude
	if distance<0 then
		distance = -distance
	end
	if distance > covermindistance then -- check if camera is far away enough
		model.ExampleBody.Visible = true
		local pos = planets.ExampleBody.CenterPos.Value:Lerp(camera.CFrame.Position, 0.8)
		model.ExampleBody.Part.Position = pos -- set position of the part in the viewport frame
	else
		model.ExampleBody.Visible = false
	end
	-- Camera
	newcamera.CFrame = camera.CFrame
	campart.CFrame = newcamera.CFrame*CFrame.new(0,0,-500)
	newcamera.FieldOfView = camera.FieldOfView
end)

I don’t know if it works or not?

What did you change in this script?

I changed it so it uses FindFirstChild for safety, cached the variables for better performance, added checks to stop unnecessary updates, made the size update a function, and now the camera and visibility only update when needed

In short, I optimized it a little bit

But idk its works or not? because i dont have these viewports

Isn’t this the same script? I can’t find any changes you described in it.

if lastCameraCFrame == nil or lastCameraCFrame ~= camera.CFrame then
    newcamera.CFrame = camera.CFrame
end

It skips hundreds of unnecessary operations and provides better optimization, by the way, this is only part of it.

Working or not?

Nope, sadly still the same thing.

I’m sorry, I hope you find a solution :slight_smile:
Goodluck

1 Like

Can you also show me your code? So I can compare them and see whats wrong?

Could you send me a location file? I can’t get the provided script to do what you’re looking for. In any case, if each ViewportFrame is a Planet, this causes the FPS to be deprioritized when updating the Viewport. An example was once I made a weapon visualizer where the weapons only rotated, but it had weird “gaps.”

you didn’t move the camera…

I realize that. I tested turning the camera and the cubes continue to move across the screen smoothly. Though, I believe my example was oversimplified and wasn’t what he was trying to do.

1 Like

I’m not sure how to fix your code, but I’m assuming you’re using ViewportFrames to render objects that are very far away. You might benefit from supporting this feature request:

Also see this update, it might be relevant:

You mean this?

Each viewport frame represents a planet, and inside it, theres a part to visualize.

1 Like

I understand. So with a for loop, you update the object’s position in the Viewport based on where it is in the Workspace? Can you send me a screenshot of your Workspace?