Read this post from the RBXDev First:
https://devforum.roblox.com/t/repro-touched-events-delayed/38118
Touched event in parts will cause lag when they collide and get fired multiple times. Causing the server's late respondent.
Like this script inside an NPC:
local NPC = script.Parent local RootPart = NPC.HumanoidRootPart RootPart.Touched:connect(function(part) if not part.Parent then return end if not part.Parent:FindFirstChild('Humanoid') then return end local char = part.Parent local hum = char.Humanoid print('It is a player!') end)
In-game the player touches the NPC. The server performance goes 30% down and the script printed 50x times.
But is there a way that make this still possible? If then, how?
Sure, use a debounce. I like using tables because then the debounce time corresponds to each player and the last time they touched that npc, rather than a variable that changes everytime the npc is touched.
local NPC = script.Parent local RootPart = NPC:WaitForChild("HumanoidRootPart") --[[ local touchedLast = {} local debounce = .5 setmetatable(touchedLast, { __index = function(self, key) -- if the player isn't in the table, set and return their new index self[key] = debounce return self[key] end }) RootPart.Touched:Connect(function(part) if not part.Parent then return end local player = game.Players:GetPlayerFromCharacter(part.Parent) if player then local index = touchedLast[player.Name] -- if the last time we touched the npc is more than whatever debounce is if (tick() - index) >= debounce then -- update the last time they touched it touchedLast[player.Name] = tick() end end end) --]] -- Basic way people do it. local debounce = true local bounce = .5 RootPart.Touched:Connect(function(part) if not part.Parent then return end local player = game.Players:GetPlayerFromCharacter(part.Parent) if player and debounce then debounce = false print('do something') wait(bounce) debounce = true end end)