Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

How to make sure this script fires only once? Get Touching Parts

Hey guys, so I'm working on a reward system when killing enemies to reward everyone in a specific area. I'm doing this using a GetTouchingParts system, and it's working pretty well, the only problem is, it keeps awarding the player, even if I do script:Remove() right after I do the awards, but I'm also thinking if I do script:Remove() then the other players wont be able to be rewarded, could I get some help?

Script:

local part = script.Parent

part.Touched:Connect(function() 
	
	while wait(1) do
		
	    local touching = part:GetTouchingParts() 
		for _, p in next, touching do
			
			if p.Parent:FindFirstChild("UpperTorso") then
				
				local plr = game.Players:GetPlayerFromCharacter(p.Parent)
				local cash = plr:WaitForChild("leaderstats").Cash
				local exp = plr.Level.Current

				cash.Value = cash.Value + 5
				exp.Value = exp.Value + 2
				script:Remove()

	    	end
		end
	end
end)

1 answer

✓ Accepted answer

There are 2 ways to fire your event only once. One is to use debounce, and another is to disconnect your event.

Using a debounce

local debounce = false --False is activated, True is activated

local part = script.Parent

part.Touched:Connect(function() 
  if not debounce then --Alternative: if debounce == false
    debounce = true --Once true, the event will not be playing again.
    while wait(1) do

        local touching = part:GetTouchingParts() 
        for _, p in next, touching do

            if p.Parent:FindFirstChild("UpperTorso") then

                local plr = game.Players:GetPlayerFromCharacter(p.Parent)
                local cash = plr:WaitForChild("leaderstats").Cash
                local exp = plr.Level.Current

                cash.Value = cash.Value + 5
                exp.Value = exp.Value + 2
                script:Remove()
		  end
            end
        end
    end
end)

Now, even if you use the debounce, the game may be using more resources than necessary, so it's better to disconnect the event.

Using the Disconnect() event

local connection --We need a variable in order to disconnect it. Default is nil.

local part = script.Parent

connection = part.Touched:Connect(function() --The variable has to equal the event.

    while wait(1) do

        local touching = part:GetTouchingParts() 
        for _, p in next, touching do

            if p.Parent:FindFirstChild("UpperTorso") then

                local plr = game.Players:GetPlayerFromCharacter(p.Parent)
                local cash = plr:WaitForChild("leaderstats").Cash
                local exp = plr.Level.Current

                cash.Value = cash.Value + 5
                exp.Value = exp.Value + 2
                script:Remove()
		  
		  connection:Disconnect() --This stops the event from running again.
            end
        end
    end
end)

3 comments

0

Thanks for trying, but this still doesn't work, I'm still able to just stand next to it once it's died and get like 20 exp when I should only get 2, is this because multiple of my body parts are touching so it counts me as "multiple players" and counts every part as a player? if so, any clues on how i could solve that? Would there be any luck in trying something like cancelling out a player ID or

0

Remove the for loop and replace it with the hit parameter and do if game.Players:GetPlayerFromCharacter()

0

but wouldnt that only work if one character was within the box? I want every player in that range to get the money and exp, but if i took away the loop, i feel like it would only give it to the first character it registered

This discussion is preserved as it was. New answers, comments, and votes are closed.