Check if there is any GUI on the player's screen

Hello. It is a pretty simple question but just to clarify. Is there a way, through a script, I can check if there is any frame visible on the player’s screen? I don’t feel like writing 100 if statements. \

Thanks!

Yes. You can use either GetChildren() or GetDescendants() alongside Player.PlayerGui,within a loop - and check if those children are visible or not.

Can you send an example/video on how to do this? Im not that good with loops.

make some sort of loop and check if there is any “Gui.enabled”, (inside [StarterGui]

if there is alot of frames just do the same thing, but with [Frame.Visible]

local GS = game:GetService("StarterGui")

for _,Gui in pairs(GS:GetChildren()) do
	if Gui:IsA("ScreenGui") then -- Without this, it may drop an error since it will loop all items inside of [StarterGui]
	print(Gui.Name) -- 
		if Gui.Enabled == true then -- or Frame.Visible
		--do actions
		else
			-- nothing
		end
		
	end
end

So I am trying to check every frame in the game. Would I have to do this for every screen GUI?

you will need to do something like this then:

local GS = game:GetService("StarterGui")

for _,Object in pairs(GS:GetDescendants()) do -- will get everything
	
	if Object:IsA("ScreenGui") then -- Looping through all "ScreenGuis", checking if any of them is ''Enabled == true or whatever"
		
		print(Object.Name)
		
		if Object.Enabled == true then 
			
			--do actions
			
		else if Object:IsA("Frame") then -- Checking if Inside [StarterGui] or inside any [GUI], has any Frames, since ''GetDescendants" is looping and searching for [Frames]
				
				if Object.Visible == true then
					
					--if the Frame IS VISIBLE then do some stuff here
				end
				--Checks if any frame was located
				
			else
				-- do nothing
			end			
		end		
	end
end


i think this may help

1 Like

Just using my scripting knowledge, I looked at it and it doesn’t make sense. Its saying object is the descendants of StarterGUI. All of the descendants of startergui are screenGUI’s so it’s not possible for the object a frame. Im not that good with loops, but im pretty sure its not going to check all the frames in all the starterguis.

Just to give you more context as to what I am trying to do, im trying to make it so when a player touches a part, it makes sure no other gui is visible on a player’s screen.

1 Like

yea i just noticed that, since i only tested once and i forgot to test it out, i’ll check and see a solution rn

for _,Object in pairs(GS:GetDescendants()) do -- will get everything
	
	if Object:IsA("ScreenGui") then
		
		print("Screen Gui: " .. Object.Name)
		print"    "
		
		for _,Frames in pairs(Object:GetDescendants()) do -- Looping through all Frames inside of this Specific Gui...
			if Frames:IsA("Frame") then -- Making sure it's a Frame, and not something else
				if Frames.Visible == true then -- if somehow the Frame is Visible then:
				print("Frame Detected:" .. Frames.Name) -- It will print the Frame that was spotted
               end
				
			end
			
			
		end
		
		if Object.Enabled == true then 
			
			--do actions
			
		else if Object:IsA("Frame") then
				print("Frame found outside Guis:" .. Object.Name)
				if Object.Visible == true then
					
					--if the Frame IS VISIBLE then do some stuff here
				end
				--Checks if any frame was located
				
			else
				-- do nothing
			end			
		end		
	end
end

Honestly, just to make it simpler, can you make it so that it loops through all the frames in one specific screenGUI instead of all of them in the game? So for example, if a frame in the screenGUI it loops through is visible, then the frame does not appear.

I tried this script:

local debounce = false
local player = game.Players.LocalPlayer
game.Workspace.LogoTP.Union.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") and hit.Parent.Name == player.Name then
		if not debounce then
			local PS = player.PlayerGui.Preview
			for _,Object in pairs(PS:GetDescendants()) do -- will get everything

				if Object:IsA("Frame") then -- Looping through all "ScreenGuis", checking if any of them is ''Enabled == true or whatever"

					

					if Object.Visible == false then 
						player.PlayerGui.Preview:FindFirstChild(script.Value.Value).Visible = true
					end
				end
				
			end	
		end
		
	end


end) 	

But the gui still appears even though another frame in the screengui is visible.

local debounce = false
local player = game.Players.LocalPlayer
game.Workspace.LogoTP.Union.Touched:Connect(function(hit)
	if hit.Parent:FindFirstChild("Humanoid") and hit.Parent.Name == player.Name then
		if not debounce then
			local PS = player.PlayerGui.Preview
			for _,Object in pairs(PS:GetDescendants()) do -- will get everything

				if Object:IsA("Frame") then -- Looping through all "ScreenGuis", checking if any of them is ''Enabled == true or whatever"



					if Object.Visible == true then -- turn any spotted frame invisible
						Object.Visible = false
					end
				end

			end	
			--will run when loop finish turning off all frames
			player.PlayerGui.Preview:FindFirstChild(script.Value.Value).Visible = true
		end

	end


end) 	

if you don’t want to turn off all frames, then you need to create some exceptions, like this:

if Object:IsA("Frame") then -- Looping through all "ScreenGuis", checking if any of them is ''Enabled == true or whatever"

	if Object.Visible == true then -- turn any spotted frame invisible
        if Object.Name == "Player Health" or "Player Mana" or "Inventory" then
         --since you don't want to turn invisible some frames, it will check the name of some of them, and if somehow they are VISIBLE, then it will STAY VISIBILE
         --you can create this exception, ( i dind't tested it but probaly will work)
         return -- will return, but the loop will not stop! don't worry
      -- And without [Return] the script will check this condition, but will keep going... that's why
      end
      Object.Visible = false
   end
end

I don’t think you understand what I am trying to do. Im trying to make it so if there isn’t a frame in the Preview ScreenGUI that is visible then it does

	player.PlayerGui.Preview:FindFirstChild(script.Value.Value).Visible = true

If there is a frame that is visible in the Preview ScreenGUI, then it doesn’t run.

This is a good workaround if I can’t find a fix though.

It completely ruins some of the visible frames though, so im not sure.

kinda hard to understand what you trying to do but

ARE you trying to check [This gui] then if any frame IS VISIBLE then [the script will not run] ?

Yep, you got it exactly right.

Not sure if I am understanding you correctly, but to check if ANY frame is visible on the player’s screen (excluding roblox GUIs that are parented to CoreGui) you would use the following code, or something similar.

local visibleFrames = {}
for v, element in pairs(game:GetService("Players").LocalPlayer.PlayerGui:GetDescendants()) do 
if element:IsA("Frame") and element.Visible or (element:IsA("Frame") and element.BackgroundTransparency < 0.8) then table.insert(visibleFrames, element) end
end
if visibleFrames[1] then 
-- do something if any frame is visible
end

Please note this is a client sided script, if you want it to be server sided, replace the local player with a normal player object from the server. Please tell me if I’ve made any errors. (this code is not tested, but will most likely work)

edit: you can also remove the transparency part or adjust it to your liking.

What do I make visibleFrames if there isn’t any gui open? I want it so, if there isn’t any gui open, than the new gui is visible. If there is a frame open, then the gui does not appear.