Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
0

What's the proper way to prevent multiple touch events going off when providing rewards?

Asked by 7 years ago

I have this obstacle course demo. It spawns a map, the player completes it and touches a win block. This block is meant to increment the number of wins the player has. However, it goes off more than once when the player initiates contact with the block. I have attempted to create a table to store past winners to avoid this, but it will not work.

local beenAwarded = {} --used to store winner names (those who touched the block)

script.Parent.Touched:connect(function(hit)
        if hit.Parent:FindFirstChild("Humanoid") then
            local character = hit.Parent.Humanoid
            print "human found"
            local plrname = hit.Parent.Name
            local plr = game.Players:FindFirstChild(plrname)
            if plr then
                local stats = plr:FindFirstChild("leaderstats")
                if stats then
                    wait(.1)
                    plr.Character.HumanoidRootPart.CFrame = CFrame.new(game.Workspace.SpawnLocation.Position)
                    if beenAwarded[plr] then return end -- if the player has been added to the table it ends the function
                    table.insert(beenAwarded, plr) -- otherwise the player is added here (i have tried the same thing using the player name, same result)
                    local wins = stats.Wins
                    wins.Value = wins.Value + 1
            end
        end
    end
end)

0
what do you mean make the event a variable? & i can't use a debouce because the delay before the touch can be used again is not something i can have WillContinues 20 — 7y
0
Why not just use a debounce? KingLoneCat 2642 — 7y

1 answer

Log in to vote
0
Answered by
Azarth 3141 Moderation Voter Community Moderator
7 years ago
Edited 7 years ago

1. Your script isn't working because you're attempting to find plr with a dictionary-style based type of search, yet you're using table.insert().

If you want to use the dictionary style, you'd do this.

if beenAwarded[plr.Name] then 
    return 
end

beenAwarded[plr.Name] = plr

2. Use GetPlayerFromCharacter() to get the player and base every variable after that on the player, not hit. local plr = game.Players:GetPlayerFromCharacter(hit.Parent)

local beenAwarded = {} --used to store winner names (those who touched the block)
local spawn_pos = workspace:WaitForChild("SpawnLocation")

script.Parent.Touched:connect(function(hit)
    if hit.Parent then
        local plr = game.Players:GetPlayerFromCharacter(hit.Parent)
        if plr then
            local plrname = plr.Name
            local character = plr.Character
            local stats = plr:FindFirstChild("leaderstats")
            local hum = character:findFirstChild("Humanoid")
            if hum and hum.Health > 0 then 
                if stats and not beenAwarded[plrname]  then
                    beenAwarded[plrname] = plr
                    local wins = stats.Wins
                    wins.Value = wins.Value + 1                 
                end
                character:MoveTo(spawn_pos.Position)
            end
        end
    end
end)

0
Why not just use a debounce? KingLoneCat 2642 — 7y
0
If he doesn't want them to be-able to win again, debounce won't stop that. He should continue to use a table and remove them from it after the player gets teleported though. Azarth 3141 — 7y
Ad

Answer this question