help, What I hope is that when the player touches Part1, player will have 5 seconds to touch Part2, after which the player will receive the badge if the player leaves or dies, it will be cancelled, and the player should touch Part1 again.
Character Is Not Valid Of UserId Instead Character.Parent.UserId
or to get a player you need game.Players:FindFirstChildOfClass("Player")
and you can get a userid player.UserId
Both parts need to detect .Touched
. When the first part is hit, the script should store this information in a table, so that the function called when the second part is touched may know whether the player is eligible to be awarded a badge.
Adding to what @ahmetygci34 said, Player is an object that represents a player in game and is a member of the Players service. Character is a model in workspace players actually move around. Player.Character
is a reference to this object.
BadgeService performs web requests, so the calls, although hardly, can be exhausted. They might also fail. pcall
makes sure the code is safe.
I added comments to explain what each part does. The script is tested but please let me know if you find a bug.
Code
local Players = game:GetService("Players")
local BadgeService = game:GetService("BadgeService")
local part1 = workspace.Part1
local part2 = workspace.Part2
local BADGE_ID = 2607888591101161
local ALLOWED_TIME_BETWEEN_TOUCHES = 5 -- seconds
-- badgeOwners keeps track of all players in game
-- that own the badge as an array, e.g. {Player1, Player2, ...}
local badgeOwners = {}
-- lastPart1TouchTime stores the last time player has touched
-- Part1 in form of a dictionary, e.g. {[Player1] = time, ...}
local lastPart1TouchTime = {}
-- When Part1 is touched, lastPart1TouchTime is updated
part1.Touched:Connect(function(hit)
local player = Players:GetPlayerFromCharacter(hit.Parent)
if player then
lastPart1TouchTime[player] = os.time()
end
end)
-- When Part2 is touched, the badge is awared if eligible
part2.Touched:Connect(function(hit)
local player = Players:GetPlayerFromCharacter(hit.Parent)
if player then
-- Has it been more than ALLOWED_TIME_BETWEEN_TOUCHES seconds
-- since the touch of Part1? Return
if (os.time() - (lastPart1TouchTime[player] or 0)) > ALLOWED_TIME_BETWEEN_TOUCHES then
print("Not eligible")
return
end
-- Does the player already have the badge? Return
if table.find(badgeOwners, player) then
print("Already owns the badge")
return
end
-- Attempt to award the badge. The request may occasionally fail
local success, result = pcall(function()
BadgeService:AwardBadge(player.UserId, BADGE_ID)
end)
-- Successfully awared badge places the player among
-- the badge owners
if success then
table.insert(badgeOwners, player)
print("Awarded the badge")
else
print("Failed to award the badge")
end
end
end)
-- When the player joins the game, check whether they
-- have the badge with a couple of retries
Players.PlayerAdded:Connect(function(player)
local success, result
local retries = 0
repeat
success, result = pcall(function()
BadgeService:UserHasBadgeAsync(player.UserId, BADGE_ID)
end)
retries += 1
until success or retries == 3
if success == true and result == true then
table.insert(badgeOwners, player)
end
end)
-- Once the player leaves, clear them from both tables
Players.PlayerRemoving:Connect(function(player)
lastPart1TouchTime[player] = nil
table.remove(badgeOwners, table.find(badgeOwners, player))
end)
This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.