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

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

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.

1 comment

0

Is this a local script or a server script?

1 answer

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

2 comments

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.

0

Well, if you have the player object, you can do Player.Name to get the name of the player.

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