What do you want to achieve? Keep it simple and clear!
I want a button that prints “hi” when stepped on. It should only happen once, and it can happen again after being stepped on again.
What is the issue? Include screenshots / videos if possible!
The issue is that it prints multiple times whenever the player walks on it.
Video of issue:
What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I saw that people normally use debounces but they just slow down the printing.
I tried to add a table system where it adds the player’s character that touched the button in a table thats checked whenever the character touches the button and removes it if not touched, but it had the same multiple printing issue before.
My code:
local button = script.Parent
button.Touched:Connect(function(p)
if p.Parent:FindFirstChild("Humanoid") then
local char = p.Parent
print("hi")
end
end)
add a debounce im assuming ur problem is it prints a load of times this is because the listener fires a bunch of times because its very fast so a debounce will look like this
local button = script.Parent
local Debounce = 0
button.Touched:Connect(function(p)
if tick() >= Debounce then
Debounce = tick() +1
if p.Parent:FindFirstChild("Humanoid") then
local char = p.Parent
print("hi")
end
end
end)
tick() gets the current time in seconds
every time the code runs we add one to the value of time and make the code check if its past that time so it can run again and add another 1
local button = script.Parent
local touchFunction = button.Touched:Connect(function(p)
if p.Parent:FindFirstChild("Humanoid") then
local char = p.Parent
print("hi")
touchFunction:Disconnect()
end
end)
Well without typing actual code ill try to explain a simple methodology to this as best I could.
In the touched function you determine which player steps on the part, by just checking the parts ancestor. From there you can assign a denounce value to that particular player regarding that particular part. In short it will represent that the player is currently on the part. You then have a touch ended function that fires when a player leaves the part. In the same manner you get the ancestor of the part and if it happens to be a player you reset the debounce, allowing the action to run again.
In short the moment the player touches the part, you lock the action from happening again until the player leaves the part and the touch ended function fires.
That’s likely due to the fact that the walking animation causes the players feet to step off the ground. A hacky solution would be to just use a taller invisible block for the touch/touchended events. Instead though you could look into shooting rays from the player and/or the block, of even possibly using region3 to detect whether a player is in an area.
(Sorry for the late reply, I was eating dinner) I misread your post, sorry! You can probably work something out with magnitude to tell if the player is still close to it or not.
A great way to achieve this while still using the “.Touched” and “.TouchEnded” events is as follows. Firstly, the part’s “.TouchEnded” connection should only be created when its “.Touched” connection is fired. Secondly, the “hit” part which results in both events firing, should be checked for equality, that way we can determine exactly when the “hit” part began/stopped touching some other part.
local players = game:GetService("Players")
local part = script.Parent
part.Touched:Connect(function(hitStart)
local hitModel = hitStart:FindFirstAncestorOfClass("Model")
if hitModel then
local hitPlayer = players:GetPlayerFromCharacter(hitModel)
if hitPlayer then
print(hitStart.Name.." touched part.")
local connection do
connection = part.TouchEnded:Connect(function(hitEnd)
if hitStart == hitEnd then
local hitModel = hitEnd:FindFirstAncestorOfClass("Model")
if hitModel then
local hitPlayer = players:GetPlayerFromCharacter(hitModel)
if hitPlayer then
print(hitEnd.Name.." stopped touching part.")
connection:Disconnect()
end
end
end
end)
end
end
end
end)