Part only awarding one player

I’m a beginner and right now I’m trying to make it so when a player touches a part, they get rewarded a badge, add a win to leaderstats, and get teleported back to spawn. I want to make it so it only counts on the leaderstats once for each player. However, my problem now is when 2+ players touch the part at the same time, only the first one who touched it is rewarded. Any ideas?

local badgeService = game:getService("BadgeService")
local badgeID = 3372892239859432
local debounce = false

script.Parent.Touched:Connect(function(hit)
	local character = hit.Parent
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
	if character and player and not badgeService:UserHasBadgeAsync(player.UserId, badgeID) then
		if debounce == false then
			debounce = true
			game:GetService("BadgeService"):AwardBadge(player.UserId, 3372892239859432) -- 
			player.leaderstats.Badges.Value += 1
			wait(3)
			debounce = false
		end
	end
end)


local Pad2 = game.Workspace.Floor1

script.Parent.Touched:Connect(function(touchPart)
	if touchPart and touchPart.Parent and touchPart.Parent.Humanoid and touchPart.Parent.currentlyTeleporting.Value == false then
		local Character = touchPart.Parent
		local teleportLocation = CFrame.new(Pad2.CFrame.X, Pad2.CFrame.Y + 5, Pad2.CFrame.Z)
		Character:SetPrimaryPartCFrame(teleportLocation)

		local teleportingValue = Character.currentlyTeleporting
		teleportingValue.Value = true
		wait(3)
		teleportingValue.Value = false
	end
end)
4 Likes

Instead of adding a debounce, add an if statement to check if the player does not have the badge that is rewarded when that event occurs. It is also good practice to wrap it in a pcall as it is a function that makes an http request so if it fails you could for example retry that request.

local success, hasBadge = pcall(function()
BadgeService:UserHasBadgeAsync(player.UserId, badgeId)
end)
if success and not hasBadge then
local success, err = pcall(function()
BadgeService:AwardBadge(player.UserId, badgeId)
end)
if success then
player.leaderstats.Badges.Value += 1
else
warn(err)
end
elseif not success then
warn("It could not be verified if the player has the badge awarded.")
end)

Whenever the player touches the part, the leaderstat goes up more than 1 each time (like 4-6). Also, even though the player has the badge, the leaderstat still increases

They forgot to add a return. Here is the updated script:

local success, hasBadge = pcall(function()
    return BadgeService:UserHasBadgeAsync(player.UserId, badgeId)
end)

if success and not hasBadge then
     local success2, err = pcall(function()
         BadgeService:AwardBadge(player.UserId, badgeId)
     end)

    if success2 then
        player.leaderstats.Badges.Value += 1
    else
        warn(err)
    end
elseif not success then
    warn("It could not be verified if the player has the badge awarded.")
end)

By the way, change the top line to this. FindFirstChild returns nil if nothing is found, so your script shouldn’t error.

if touchPart.Parent:FindFirstChild("Humanoid") and touchPart.Parent.currentlyTeleporting.Value == false then
1 Like

It should look like this right? It doesn’t seem to award a badge or add to leaderstat

script.Parent.Touched:Connect(function(hit)
	if touchPart and touchPart.Parent:FindFirstChild("Humanoid") and touchPart.Parent.currentlyTeleporting.Value == false then
	local player = game.Players:GetPlayerFromCharacter(hit.Parent)
		local success, hasBadge = pcall(function()
			return badgeService:UserHasBadgeAsync(player.UserId, badgeID)
		end)

		if success and not hasBadge then
			local success2, err = pcall(function()
				badgeService:AwardBadge(player.UserId, badgeID)
			end)

			if success2 then
				player.leaderstats.Badges.Value += 1
			else
				warn(err)
			end
		elseif not success then
			warn("It could not be verified if the player has the badge awarded.")
		end
	end
end)

Did you change the very top line from this

local badgeService = game:getService("BadgeService")

to this

local badgeService = game:GetService("BadgeService")

Also, you don’t currently own the badge, right?

1 Like

Yes I did change it and yes I don’t currently own the badge

Maybe add some print statements to see where the issue is happening. Also, is this a local script or a normal/server script?

1 Like

It’s a normal script inside of a part, also this is what the top of the first script looks like

local badgeService = game:GetService("BadgeService")
local badgeID = 3372892239859432
local touchPart = script.Parent

I am not too sure if the touchPart line is right

1 Like

Try this, you accidentally put touchPart instead of hit.

if hit and hit.Parent:FindFirstChild("Humanoid") and hit.Parent.currentlyTeleporting.Value == false then

It’d be because the debounce is active when the second player touches the part?

Thank you, it works when a singular person touches it, but do you know it awards it if 2+ people touch it at the same time? If you don’t it’s fine, I can test later

I originally had it there to prevent a player from getting more than 1 “win” whenever they touched the part but yeah I finally realized it was the debounce causing the issues

It should work as long as you don’t have that debounce.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.