I've been recently trying to get into scripting again, and for some reason whenever I touch a collectible, sometimes it multiplies the score it should give (50) by some integer. (Image and video related.) I think it has something to do with multiple limbs touching the part at the same tick.
#Score doubling when collecting
1 messages · Page 1 of 1 (latest)
You need a debounce to prevent multiple limbs touching it
(btw the script's RunContext is set to Client)
debounce?
Developer Forum | Roblox
Example: --|| FederalTactical @ DevForum local Part = game.Workspace:WaitForChild("Part") local ClickDetector = Part:WaitForChild("ClickDetector") local myDebounce = true --> The player would be able to click. ClickDetector.MouseClick:Connect(function(Player) if myDebounce == true then myDebounce = false print("ClickDetector was used! \n ...
I tried it, and it's still counting multiple limbs.
How does your score increase?
Basically I put an IntValue in the player (game.Players.examplePlayer) to keep track of score, and when a collectible is touched, it increases by the collectible's ScoreGive attribute, and then the collectible disappears.
Perhaps the issue lays within the script that handles that? Because so far I don't really see an obvious issue with this code
This is the script (and module) that handles it.
Btw sorry if I take long to reply cuz this code is a bit hard to read
To be honest I am a bit confused. If the first script doesn't handle the increase on the IntValue and neither do the newer ones, which script handles it?
Or did I miss it?
it’s the first one (this)
oh i thought you meant the one that handles actually getting the IntValue in there
mb
no I mean like the script that does s.Value += part:GetAttribute("ScoreGive")or whatever
I looked back at the code and to be honest I don'T know. Though it is most likely that .Touched fires multiple times in one frame before debounce is set to false, so I'd probably do something like
-- more stuff up here
local debounce = true
c.Touched:Connect(function(p)
if not debounce then return end
debounce = false
-- more stuff here
if h and not debounce then
-- stuff
end
end)```
But it's fairly well known that `.Touched` is generally unreliable and it's not recommended to be used because there are better alternatives
** You are now Level 1! **
wrap the whole argument inside the function inside the debounce
which ones?
Just cache the plr and if that plr has already got it then do nothing
There is GetTouchingParts() and spatial query functions like GetPartBoundsInBox() or GetPartBoundInRadius()
But they are less straightforward than .Touched but provide better reliability
Generally though, like I said, .Touched is unreliable but it is also vulnerable to exploiters / cheaters
Okay. I’ll look into that.
dont you have to call that multiple times tho? i think it would be more expensive in performance
Yes and no. While they are moderately heavy in performance, it all comes down to optimization
The spatial query functions from what I know are less performance heavy than GetTouchingParts(), so calling like 5 of them every frame shouldnt be extremely bad, but thats why people generally mix Raycast with these things to make sure they arent ran unnecessarily
But if OP can't find a solution, they should probably go back to .Touched then
I FOUND A SOLUTION!
I just changed the code to check if the part that's touching is the HumanoidRootPart, which is just one object, and (i think) less expensive on performance than the ones mentioned by softimpact.
it would be less responsive tho
Also I'm not sure but if this is only a one time pickup then u could do part.Touched:Once(function())
literally the fix as well
I forgot :Once() exists LMAO
There are still some reliability issues with this for as long as you use :Connect(), so just use :Once() like the other person said as it makes the function only ever run once
i did not know that existed until now
** You are now Level 3! **
great
still connected to the .Touched event so its the same unreliability, but yeah its great
Once cleans up after itself so no