Touched Event constantly firing

So for some reason the touched event when connected to my character’s parts just keep firing like if it’s in a loop. It seems to be only a certain place since if I try it on a default baseplate it works normally. A simple script like this one:

for i, v in pairs(Character:GetChildren()) do
v.Touched:Connect(function(part)
print(tostring(part))
end)
end
--(i wrote this on my phone)

Would constantly fire the parts name over and over again, yet the same script would work fine on a default place. It doesn’t seem to relate to animations or parts inside of the character (ragdoll collision parts) either.

2 Likes

Have you tried adding a debounce?

local debounce = false
if not debounce then
  debounce = true

  for i, v in pairs(Character:GetChildren()) do
    v.Touched:Connect(function(part)
      print(tostring(part))
    end)
  end
  task.wait(1)
  debounce = false
end

That is not how to add debounce. You need to add the if statement inside the .Touched event for it to work.

1 Like

What are you wanting it to print? The part the player is standing on?

If that’s the case, this should work:

local debounce = false

game.Players.PlayerAdded:Connect(function(Player)
	local Character = Player.CharacterAdded:Wait() or Player.Character
	for i, v in pairs(Character:GetChildren()) do
		v.Touched:Connect(function(part)
			if debounce == false then
				debounce = true
				print(tostring(part))
				task.wait(1)
				debounce = false	
			end
		end)
	end
end)

So I tried your code, it seems to only merely slow down the touched signal which isn’t really optimal if someone is going fast thru a part that (for example, ragdolls them).
Normally touched would fire everytime you just touch a part and not fire again until you move or something. For me, it fires everytime I’m touching a part.
Again it seems to be only this specific place that has this issue.
I’m not sure if something is changing my position ever-so-slightly that it constantly fires the touched or not.

Im looking at this and yeah, its a loop going towards your character , since the children are in your character and they are touching each other, plus your Humanoid, and workspace items, it will repeat

There is also an error here unless i’m missing something:

for i, v in pairs(Character:GetChildren()) do
v.Touched:Connect(function(part)
print(tostring(part))
end)
end -- Error

Thats Because it IS in a loop, what you are using is called a For Loop. you Usually use Touched in a for loop when you want it to fire on multiple parts.

For Example this ServerScriptService script:

function Touched()
	print("touched")
end




for _,Parts in pairs(workspace:GetChildren()) do
	if Parts:IsA("Part") then
		Parts.Touched:Connect(Touched)
	end
end
1 Like

You’re wrong. It’s not supposed to repeatedly fire what part I’m touching. It’s only support to fire when I just touch a part.
Here’s some gifs to showcase.
They’re all using the code below in StarterCharacterScripts

local Character = script.Parent
for i, v in pairs(Character:GetChildren()) do
	v.Touched:Connect(function(part)
		print(tostring(part))
	end)
end
  1. Default Baseplate running the code: (it prints everytime I move)
    RobloxStudioBeta_ytZOHvjhds

  2. Specific game running the exact same code (it prints repeatedly, stops printing if i jump since im not touching anything.
    RobloxStudioBeta_DKYsneDekR

2 Likes

Thats Exactly what i mean, your bodyparts are touching something or themselves

My Script:

function Touched()
	print("touched")
end




for _,Parts in pairs(workspace:GetChildren()) do
	if Parts:IsA("Part") then
		Parts.Touched:Connect(Touched)
	end
end

This script is a global script, anything you touch that is a part, will print touched

Your Script:

local Character = script.Parent
for i, v in pairs(Character:GetChildren()) do
	v.Touched:Connect(function(part)
		print(tostring(part))
	end)
end

This script is looping through the Players character and is being told to fire when it touches something, and everytime it touches something, i will print what it is.

if youre trying to get the name of the object youre touching:

for _,Parts in pairs(workspace:GetChildren()) do
	function Touched(hit)
	print(Parts)
end
	
	if Parts:IsA("Part") then
		Parts.Touched:Connect(Touched)
	end
end

this shouldn’t spam the Output unless you are running around.

Yes it does, everytime the game detects you are moving on the Part, or on the part itself. It fires .Touched. if you are printing, It will spam the function unless you add a delay or stop moving.

It Aint that hard to understand.

It must be your place.

When I try it in studio with a fresh place, it only hits when I move around.
image

In a local script under the player’s Character

for i, v in pairs(script.Parent:GetChildren()) do
	if v:IsA("BasePart") then
	v.Touched:Connect(function(part)
		print(tostring(part))
		end) 
	end
end

I loaded a brand new Baseplate to test out my scripts, i used a Server Script in ServerScriptService

Empty place with script in ServerScriptService
It still only detects when I move around, and only when I hit parts I had not previously hit

image

game.Players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function(character)
		wait(5)
		print("ready")
		for i, v in pairs(character:GetChildren()) do
			if v:IsA("BasePart") then
				v.Touched:Connect(function(part)
					print(tostring(part))
				end) 
			end
		end
	end)
end)

Okay, so let’s ignore the other replies for a moment since they’re mostly off-topic and more centered upon saying you’re flat-out wrong.

Now. Let’s break this down, I’ll ask some questions, just provide the answer to best of your abilities.

  1. What is “STREET” and what properties does it have? (Screenshot preferrable)
  2. Are there multiple of these “STREET” instances?
  3. Are there any custom or otherwise enforced animations in the issue place?

Just fill me in with some of these answers and we can see if this can sort itself out.

The “STREET” part is a normal part. Just in case something is wrong with it, I copied the default baseplate and put it outside of the normal map and then used commands to fly there. It does the same.
RobloxStudioBeta_2sUpRPWIV5
2. Yes.
3. There are custom animations, but even if I put it on a default place, it still works normally and doesn’t spam it. There’s another script that flucates your walkspeed and jumppower (client-sided), but again, it works fine on the empty place.
Right now I’m looking through scripts to see if it’s actively modifying anything regarding my character.
Most modifications like smooth movement don’t seem to relate to this touch connection spam.

Okay, just as an update, a serverscript around 3.5k lines that handles pretty much 90% of the game seems to be at fault of this touch spam. Looking into it.

Most touched scripts are in the object being touched and check to see what touches the item, then checks if that item is a child of a Humanoid. If it is it gets the player from that contact and performs the section of script you want on that item or that player.
It then uses a debounce to keep it from firing again. The article posted has a good description of this phenomenon.

touched fires multiple times every time an item contacts another one. This is really problematic when using a player because they are almost always moving.

This seems to be a very simple fix.

local LastTouch = 0 --store the game tick of the last touch
local Cooldown = 0 --change cooldown

for i, v in pairs(Character:GetChildren()) do
  v.Touched:Connect(function(part)
    local Now = tick()--this moment in time
    if Now >= LastTouch+Cooldown then
        LastTouch = Now--update the last touch tick
    else
        return--cancel, need to wait more time
    end
    
    if part:IsDescendantOf(Character) then
      return --cancel, it's a part inside our own character
    end
    print(tostring(part))
  end)
end

you just need to think of it in terms of where to cancel the function (return nil) and store a timestamp and a cooldown value and it becomes trivial

2 Likes

I was suggesting that the script be taken out of the player and put into the Part you want to register the touch.
Makes it much easier to check if the item (in this case a player) touching the Part has a Humanoid inside it.
I don’t recall anyone (I’m not much of a scripter, but I have read a lot of posts about checking for touched) checking inside the player to see if the player has touched a certain Part. Seems like even if the script senses a touch from inside the player and the function has to check if it’s a player Part or the Part you want to check for then it’d start causing lag running every time, even with your debounce.

Also, if it’s a player script wouldn’t that be local, and able to be hacked?

As I understand it if it was a server script inside the Part in the workspace Clients wouldn’t be able to change the touched function.

It really depends on the purpose of the script. I imagine they have some reason for designing it this way. I personally wouldn’t, or if I did do something similar I would only check collisions on the PrimaryPart (to detect if you’re inside a part with no collisions for example without having a script in every part)

I think my reply should work for OP just fine. I’m just trying to help him with his problem rather than tell him he should be designing his system different lol

2 Likes

Also, if it’s a player script wouldn’t that be local, and able to be hacked?

Should probably mention to you the client is in charge of server touched connections involving parts owned by the network. (e.x you can turn off CanTouch on a kill brick client-side and the server-side kill-brick won’t hurt you because your client never sends the touch signal packets for the server to execute its code)
the reason it works this way is because collision detection is less expensive when it’s off-loaded to the client

source(s):
dude, trust me :wink:

3 Likes