Why doesn't the button disappear?

Scripters please help me
I wrote a script where when you touch an object, the button appears and if the player does not touch the object, it disappears

workspace.InvisibleWalls.TouchPart.Touched:Connect(function(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	game.ReplicatedStorage.EnterButtonShow:FireClient(player)
	
	if not workspace.InvisibleWalls.TouchPart.Touched then
		game.ReplicatedStorage.EnterButtonHide:FireClient(player)
	end
end)

and the script under the button itself

game.ReplicatedStorage.EnterButtonShow.OnClientEvent:Connect(function()
	script.Parent.Visible = true
end)
game.ReplicatedStorage.EnterButtonHide.OnClientEvent:Connect(function()
	script.Parent.Visible = false
end)

but if the player touched the object and moved away, the button continues to remain on the screen
Many thanks in advance for your help

2 Likes

This is not how Touched works. You understand the general grasp of it being an event, but because of this, you cannot check it in an if statement as if it were a boolean. You could use the TouchEnded event. They both aren’t highly reliable, but it will likely be perfectly fine depending on how you have this set up. (My right hand is also broken. I don’t wanna type that. even though I’m typing this specific part after I wrote the rest of the post. That part doesn’t matter sooooo… moving on!)

You also are not even checking if the player variable is actually set to something. The touched event gets triggered by anything that touches the part. This includes any geometry surrounding it, and player accessories. If it is geometry not in a player’s character, GetPlayerFromCharacter will return nil. Same thing with a player’s accessories, because the actual mesh of the accessory is under another object, not directly a child of the character. If it gets returned as nil at any point, you will be trying to fire a client with nil, which doesn’t exist.

One thing I also recommend is taking a “context” from a RemoteEvent when using them with UI like this. That way you don’t unnecessarily need multiple remotes when one can handle both functions.


Here is the fixed (and tidied up) code:

Server
local invisibleWalls = workspace:WaitForChild("InvisibleWalls")
local touchPart = invisibleWalls:WaitForChild("TouchPart")

touchPart.Touched:Connect(function(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	
	if player then
		game.ReplicatedStorage.EnterButton:FireClient(player, "Open")
	end
end)

touchPart.TouchEnded:Connect(function(hit)
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	
	if player then
		game.ReplicatedStorage.EnterButton:FireClient(player, "Close")
	end
end)
Client
local replicatedStorage = game:GetService("ReplicatedStorage")

local gui = script.Parent

replicatedStorage:WaitForChild("EnterButton").OnClientEvent:Connect(function(context)
	if context == "Open" then
		gui.Visible = true
	elseif context == "Close" then
		gui.Visible = false
	end
end)

Again, my right hand is broken. Please pardon me if there are any spelling mistakes or errors. And if there is an error, let me know!

4 Likes

Thank you so much, I realized my mistakes, I just recently started using roblox studio. And I’m sorry you had to explain all this to me. Thanks again

2 Likes

No need to apologize to me at all. It’s better you learn now than struggle later.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.