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

How to check if a player has already picked up a coin?

Asked by 1 year ago
Edited 1 year ago

Here's my situation, i've made a coin mesh and added a script to it that makes the coin spin and when picked up makes a sound and adds to the players leaderstats value. It disappears for 5 seconds before regenerating to make a new coin. Is there anyway to make it so if a player picks up a coin they have already picked up maybe a few minutes earlier, they aren't able to pick it up again without changing the wait and db value for everyone else in the server?

while wait(0.05) do
    CoinPart.CFrame = CoinPart.CFrame * CFrame.Angles(0.05,0,0)
    local function onTouched(CoinPart)
        local player = Players:GetPlayerFromCharacter(CoinPart.Parent)
        if not player then return end
        if db == false then
            db = true
            CoinTween1:Play()
            player.leaderstats.Coins.Value = player.leaderstats.Coins.Value + 1
            Sound:Play()

            wait(5)
            CoinTween2:Play()
            db = false
        end

Here is part of my script, the rest is just the info for tweens and basic variables.

0
Is this a local script or a server script? kingmaster1033r 0 — 1y

1 answer

Log in to vote
0
Answered by 1 year ago
Edited 1 year ago

You can create an attribute whenever someone claims the coin. Create it either on the script or on the coin (whichever you prefer) and set the name of the attribute to the player's name then set the value to the Boolean.

You can use the AttributeChanged event to detect when an attribute has been changed. This event will return the attribute's name. Then you can use the attribute name to get the attribute value.

For the cooldown part, you can use a coroutine. A coroutine will run code on a separate thread which will prevent the rest of the script from yielding when using wait(5).

Sorry, I ended up rewriting your script. Mainly because it was easier that way for me personally. Let me know if you have any questions.

game:GetService("RunService").Heartbeat:Connect(function()
    CoinPart.CFrame = CoinPart.CFrame * CFrame.Angles(0.05, 0, 0)
end)

CoinPart.Touched:Connect(function(hit)

    local Character = hit.Parent
    local Player = game:GetService("Players"):GetPlayerFromCharacter(Character)

    if Player then
        if not script:GetAttribute(Player.Name) then
            script:SetAttribute(Player.Name, true) 
            CoinTween1:Play()
            Player.leaderstats.Coins.Value +=  1
            Sound:Play()
        end
    end
end)

script.AttributeChanged:Connect(function(Attribute)

    local Claimed = script:GetAttribute(Attribute)

    if Claimed then
        coroutine.resume(coroutine.create(function() -- creates on a new thread so the script doesn't yield
            wait(5)
            script:SetAttribute(Attribute, not Claimed)
            CoinTween2:Play()
        end))
    end
end)

Documentation(s):

Coroutines, Attributes, AttributeChanged

0
Hi, i'm just confused on what to name the attribute, as you say I should put the players name but I don't actually know the players name. (Except from myself playtesting) I've added the boolean value attribute to the script. tumtindy 36 — 1y
0
Well, if you have the player object, you can do Player.Name to get the name of the player. xInfinityBear 1777 — 1y
Ad

Answer this question