Gui not always showing

Hello, I am currently creating a game with rounds and whenever a round has started, the player can walk towards a door and touch it and a team GUI will pop up. But sometimes when you touch the door, it’s not working. I have seen this issue in some other Roblox games as well before so I don’t know if it’s because of my code or if it has to do something with Roblox. Can anyone tell me if it’s my code and if so what I need to change?

I have tried to find a solution on the internet, but I couldn’t find anything about this.

This is the code:

local debounce = false
local InRound = game.ReplicatedStorage.RoundSystemValues.InRound

game.Workspace.TeleportationFolder.TeamChoose.Touched:Connect(function(hit)
	if InRound.Value == true then
		if not debounce then
			debounce = true 
			if game.Players:GetPlayerFromCharacter(hit.Parent) then
				game.ReplicatedStorage.EventsFolder.ShowGUI:FireClient(game.Players:GetPlayerFromCharacter(hit.Parent))
			end
			wait(2)
			debounce = false
		end
	end
end)

You should always be checking for the player first thing in a .Touched function. As is, debounce will be true for 2 seconds, even if a player is not found. This can mean a player’s accessory can hit first, and so the .Touched function will effectively be disabled for 2 seconds, in which the player could’ve already walked past the part.

Isn’t this checking for a player?

if game.Players:GetPlayerFromCharacter(hit.Parent) then

Well you should replace the position of the thing that checks for the player.

if game.Players:GetPlayerFromCharacter(hit.Parent) then
   if not debounce then
      debounce = true
      --rest of the code
   end
end

The reason to you needing to do this is because you activated the cooldown before even checking if a player touched it. (Since the if statement comes later the debounce = true)

I would recommend putting a debounce per player, rather than one debounce for everyone, the reason is because sometimes, a player can touch the door right after another player touches the door, also, I recommend putting this client-side cause Touched events that involve a part a player has network ownership of will be fired by the owning player and replicated to the server, so it is just sending info to the server only for it to be sent back to the client, here is what you should do in a LocalScript

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RoundSystemValues = ReplicatedStorage:WaitForChild("RoundSystemValues")
local InRound = RoundSystemValues:WaitForChild("InRound")

local Players = game:GetService("Players")
local LocalPlayer = Players.LocalPlayer

local TeleportationFolder = workspace:WaitForChild("TeleportationFolder")
local TeamChoose = TeleportationFolder:WaitForChild("TeamChoose")

local debounce = false

TeamChoose.Touched:Connect(function(hit)
	if InRound.Value then
		local plr = Players:GetPlayerFromCharacter(hit.Parent)
		if plr and plr == LocalPlayer and not debounce then
			debounce = true
			-- show the GUI
			wait(2)
			debounce = false
		end
	end
end)
1 Like

Where do you recommend putting the script, in the part it self? The script currently is located in ServerScriptService

The LocalScript should be located in the StarterGui parented to your GUI that controls switching teams

Okay I tested it and it worked! Thanks a lot!