Hi, in my game I have a folder containing the game’s main collectible - snowflakes. These are represented by parts. When the player collects a snowflake I need the game to remove the snowflake instance from workspace and remember not to load it again when the player rejoins.
This means I need to give each snowflake part some kind of unique identifier. I could add an IntValue into each part with a unique ID or I could give each one a unique name. Both of these solutions are a bit tedious if I’m adding a couple hundred. Further, I can’t rely on a script to do it when the server starts up with a loop as it might not necessarily iterate through each one in the same order.
The best solution I can think of is to use the command bar to quickly name them but I was wondering if anybody has any better ideas? Thanks.
Hi, I’ve never tried anything like this before but you could try using their x and z positions to identify them as long as they aren’t going to be moving. If you saved a dictionary of all snowflakes using the XZ position as a key and a bool for collected or not then you could just load this data for each player as the start of the game.
Hey, thanks for the suggestion! Sadly I’d like to be able to adjust their positions slightly without undoing their collected status, otherwise this would’ve been perfect. Thanks anyway!
I think the best way to do this is to use the command bar as you’ve said. You can then just loop through and append the index to the end of the name of the snowflake.
e.g.
for i, child in pairs(folder:GetChildren()) do
child.Name = child.Name .. i
end
So I was just working on this with @MatthewAmity, this system will add int values into the snowflakes to be used as their unique id’s. It also accounts for already existing snowflakes and continues any new snowflakes from the latest unused id’s. for e.g.
If you create 50 snowflakes and use this script in the command bar it will id them from 1 to 50
If you then add another 50 in, the script will find the max id as 50 and id the new ones from 51 - 100
NOTE: Any newly placed snowflake must not have “UniqueIdNumber” IntValues in them so be careful about copying and pasting with this method.
local WS = game:GetService("Workspace")
local Snowflakes = { }
for index, descendant in ipairs(WS:GetDescendants()) do
if descendant.Name == "Snowflake" then
table.insert(Snowflakes, descendant)
end
end
local currentSnowflakeMax = 0
for _, snowflake in pairs(Snowflakes) do
local snowflakeUniqueId = snowflake:FindFirstChild("UniqueIdNumber")
if snowflakeUniqueId then
if snowflakeUniqueId.Value > currentSnowflakeMax then
currentSnowflakeMax = snowflakeUniqueId.Value
end
end
end
for _, snowflake in pairs(Snowflakes) do
local snowflakeUniqueId = snowflake:FindFirstChild("UniqueIdNumber")
if snowflakeUniqueId == nil then
local newUniqueId = Instance.new("IntValue")
newUniqueId.Name = "UniqueIdNumber"
newUniqueId.Value = currentSnowflakeMax + 1
newUniqueId.Parent = snowflake
currentSnowflakeMax = newUniqueId.Value
end
end
Thanks but unless I’m misunderstanding, the ID generated for a given snowflake wouldn’t be the same on every server as it’s random everytime right? So I can’t look up that ID in the datastore to check whether it’s already been collected?
I think he intended for it to be used in a string value stored in the snowflake. Or maybe as the snowflakes name?
Using this would prevent you from having to loop over the existing snowflakes to get the current max id and instead you would just loop over the new ones and add a string value with the id generated by this in it.
You would then use the StringValues Value as the Unique ID for the datastore.