I'm having trouble with the Touched event. Essentially I'm trying to make interact-able (?) shops. When the player touches an invisible part the script displays a prompt ("Press E to interact"). When the player presses E it then displays the shop GUI.
The prompt should obviously disappear once the player has pressed E and it should un-queue the E key from ContextActionService, however it appears this isn't happening every time - sometimes if you press E the prompt will stay on screen and then disappears when you press E a second time.
I added a couple of print()s with timestamps and it looks like the Touched event is being fired multiple times (particularly when walking through the invisible part) causing the PROMPT.SHOW() function to run multiple times as well.
Is there a fix for this or am I better moving away from the Touched event altogether? If so what is the best/most efficient alternative? Code is below, thanks
local INPUT = game:GetService("ContextActionService")
local PLAYER = game:GetService("Players").LocalPlayer
local CHARACTER = PLAYER.Character
local TORSO = CHARACTER:WaitForChild("HumanoidRootPart")
local ALL_SHOPS = game.Workspace:WaitForChild("Shops")
local TOUCHING = nil
local function OPEN_SHOP(_, STATE)
if STATE == Enum.UserInputState.Begin then
INPUT:UnbindAction("OpenShop")
local HUMANOID = CHARACTER:WaitForChild("Humanoid")
local LAST_WALKSPEED = HUMANOID.WalkSpeed
HUMANOID.WalkSpeed = 0
HUMANOID:SetStateEnabled(Enum.HumanoidStateType.Jumping, false)
script.Parent.Prompt.Visible = false
local UI = script.Parent.Frame
UI.ExitBtn.MouseButton1Down:Connect(function()
UI.Visible = false
if TOUCHING ~= nil then
INPUT:BindAction("OpenShop", OPEN_SHOP, false, Enum.KeyCode.E)
script.Parent.Prompt.Visible = true
end
HUMANOID.WalkSpeed = LAST_WALKSPEED
HUMANOID:SetStateEnabled(Enum.HumanoidStateType.Jumping, true)
end)
UI.ScrollingFrame:ClearAllChildren()
UI.TotalTxt.Text = "Total: £0.00"
UI.ShopNameTxt.Text = TOUCHING.Parent.Name
local ITEMS = require(TOUCHING.ModuleScript)
for i, details in pairs(ITEMS) do
local FRAME = script.ItemFrame:Clone()
FRAME.Position = UDim2.new(0, 0, 0, FRAME.Size.Y.Offset * (i - 1))
FRAME.ImageLabel.Image = details[2] or FRAME.ImageLabel.Image
FRAME.ItemTxt.Text = "£"..tostring(math.floor(details[3] * 100) / 100).." "..details[1]
FRAME.Parent = UI.ScrollingFrame
end
UI.Visible = true
end
end
local PROMPT = {
SHOW = function()
print("Showed prompt @ "..os.time())
INPUT:BindAction("OpenShop", OPEN_SHOP, false, Enum.KeyCode.E)
script.Parent.Prompt.Visible = true
end,
HIDE = function()
INPUT:UnbindAction("OpenShop")
script.Parent.Prompt.Visible = false
end,
}
TORSO.Touched:Connect(function(newPart)
print("Touched new part: "..newPart.Name)
if newPart:IsDescendantOf(ALL_SHOPS) and TOUCHING == nil then
TOUCHING = newPart
PROMPT.SHOW()
end
end)
TORSO.TouchEnded:Connect(function(oldPart)
if oldPart == TOUCHING then
TOUCHING = nil
PROMPT.HIDE()
end
end)

1 comment
add a debounce here is a vid on how to use debounce if u dont know already: https://www.youtube.com/watch?v=HoZkuvd6RPA&t=0s