I’ve made some code to check when a player is stepping on a part, the shop GUI shows. But when I move around on the part, the shop GUI flashes. Any ideas to stop the flashing?
My script:
local myPart = script.Parent
local Players = game:GetService("Players")
local function onTouch(hit)
local player = Players:GetPlayerFromCharacter(hit.Parent)
if player then
player.PlayerGui.ShopGUI.Enabled = true
end
end
local function onUnTouch(hit)
local player = Players:GetPlayerFromCharacter(hit.Parent)
if player then
player.PlayerGui.ShopGUI.Enabled = false
end
end
myPart.Touched:Connect(onTouch)
myPart.TouchEnded:Connect(onUnTouch)
The reason is because Touch and TouchEnded fire multiple times when the player touches it since their character has so many parts. To solve this you want to keep track of the player who touched the part with a table
local touchingplayers = {}
local myPart = script.Parent
local Players = game:GetService("Players")
local function onTouch(hit)
local player = Players:GetPlayerFromCharacter(hit. Parent)
if player and not table.find(touchingplayers,player) then
player.PlayerGui.ShopGUI.Enabled = true
table.insert(touchingplayers,player)
end
end
local function onUnTouch(hit)
local player = Players:GetPlayerFromCharacter(hit. Parent)
if player and table.find(touchingplayers,player) then
player.PlayerGui.ShopGUI.Enabled = false
table.remove(touchingplayers,table.find(touchingplayers,player))
end
end
myPart.Touched:Connect(onTouch)
myPart.TouchEnded:Connect(onUnTouch)
Okay after some tinkering i got the right code:
Server
local h
local part = workspace.Part
part.Touched:Connect(function(hit)
if hit.Parent:FindFirstChild('Humanoid') then
if h then return end
h = hit
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
game.ReplicatedStorage.RemoteEvent:FireClient(player,true)
end
end)
part.TouchEnded:Connect(function(hit)
if not hit.Parent:FindFirstChild('Humanoid') then return end
if hit ~= h then return end
local player = game.Players:GetPlayerFromCharacter(hit.Parent)
game.ReplicatedStorage.RemoteEvent:FireClient(player,false)
h = nil
end)
Client:
local sh = script.Parent.ShopGui
game.ReplicatedStorage.RemoteEvent.OnClientEvent:Connect(function(s)
if s then sh.Enabled = true else sh.Enabled = false end
end)
What I am doing here is when the part is touched I’m storing the part that hit it in a variable and when touch is ended i will stop the function if the part that stopped touching isnt what hit it.
Disclaimer
If you have an animation that hinders the touching part then you have to make a few adjustments.
Eg. I have levitation animation and this caused some issues with my char’s leg hitting the part since my char is hovering, so i lifted the part a bit.
You need to learn about debouncing and also you should probably learn about remote events to and fire to the client for smoothness. Since only the player will have the shopgui enabled anyway.
Honestly, even if you did introduce debouncing. I bet players would still be frustrated since touch events are not always accurate and can be quite weird. There’d be times where they touch the part and the GUI doesn’t open, and vice versa.
Therefore, I recommend using proximityprompts on the part instead. If you don’t know how they work, I recommend you learn them.
I’m pretty sure most games do this too, instead of touched events.
Prox prompts are a good idea i admit. But debouncing for this is a bit problematic for this since the game doesn’t care about which part left it and will keep setting it to false