You can write your topic however you want, but you need to answer these questions:
-
What do you want to achieve? Keep it simple and clear!
I want to save player attributes with SetAsync (boolean mostly) that specify if a player owns a specific vehicle. So when the player rejoins the game, or loses their vehicle they can go to a spawn point and if they own the vehicle it will spawn back. -
What is the issue? Include screenshots / videos if possible!
The attribute changes in game but the script I’m using to save them doesn’t work correctly, so when the player rejoins their attribute resets to default (false). It seems to load the attribute on PlayerAdded but the value does not change on PlayerRemoving when the save is happening, nor anytime else so far as I can tell. This is the script for the Attributes saving, I put this in ServerScriptService:
local players = game:GetService(“Players”)
local datastoreService = game:GetService(“DataStoreService”)
local datastore = datastoreService:GetDataStore(“PlayerAttributes”)local AttributeList = {
SportsCar = {“boolean”,“false”},
SUV = {“boolean”,“false”}
}local FromStringFunctions = {
number = tonumber,
boolean = function(var)
if var == “true” then
return true
else
return false
end
end
}local ToStringFunctions = {
number = tostring,
boolean = function(var)
if var then
return “true”
else
return “false”
end
end,
}players.PlayerAdded:Connect(function(Player :Player)
local Data
xpcall(function()
Data = datastore:GetAsync(Player.UserId)
end, function(err)
Player:Kick(“Error Loading Credentials”…err)
end)
if not Data then
Data ={}
end
for index, value in pairs(AttributeList) do
if not Data[index] then
Data[index] = FromStringFunctionsvalue[1]
end
end
for index,value in pairs(Data) do
Player:SetAttribute(index,value)
print(“Attributes Set”)
local atts = Player:GetAttributes()
local att = Player:GetAttribute(“SportsCar”)
print(att)
end
end)players.PlayerRemoving:Connect(function(Player :Player)
local Data = {}
for index,value in pairs(AttributeList) do
Data[index] = Player:GetAttribute(index)
endlocal Success = true
local N = 0
repeat
if not Success then
wait(0.3)
end
N += 1
local err
Success,err = pcall(function()
datastore:SetAsync(Player.UserId,Data)
end)
if err then
print(err)
end
until Success or N >= 5
end)game:BindToClose(function()
wait(3)
end)
and this is the script inside the part which changes the attribute:
function sportscarPickup (partTouching)
if partTouching.Parent:FindFirstChild(“Humanoid”) then
local player = game.Players:GetPlayerFromCharacter (partTouching.Parent)
local human = partTouching.Parent:FindFirstChild(“Humanoid”)
if player.leaderstats.Coins.Value >= 10000 then
player.leaderstats.Coins.Value = player.leaderstats.Coins.Value - 10000
local hasCar = human:SetAttribute(“SportsCar”, true)
print ("Spent Coins: " … player.leaderstats.Coins.Value)
local newSportscar = game.ReplicatedStorage.SportsCar:Clone()
newSportscar.Parent = game.Workspace
script.Parent:Destroy()
endend
end
script.Parent.Touched:Connect (sportscarPickup)
Both are Server scripts.
- What solutions have you tried so far? Did you look for solutions on the Developer Hub?
I have looked for solutions on here but haven’t found exactly what I’m looking for. I have tried adding several prints to find out what is happening. It’s strange because the attribute changes to true in game and when tested in studio and the car spawns in as it should but in the saving script the attribute does not seem to change from the default value all the way through, every print statement returns the attribute as false ;
players.PlayerAdded:Connect(function(Player :Player)
local Data
xpcall(function()
Data = datastore:GetAsync(Player.UserId)
end, function(err)
Player:Kick("Error Loading Credentials"..err)
end)
if not Data then
Data ={}
end
for index, value in pairs(AttributeList) do
if not Data[index] then
Data[index] = FromStringFunctions[value[1]](value[2])
end
end
for index,value in pairs(Data) do
Player:SetAttribute(index,value)
print("Attributes Set")
local atts = Player:GetAttributes()
local att = Player:GetAttribute("SportsCar")
print(att)
end
end)
players.PlayerRemoving:Connect(function(Player :Player)
local Data = {}
for index,value in pairs(AttributeList) do
Data[index] = Player:GetAttribute(index)
end
local Success = true
local N = 0
repeat
if not Success then
wait(0.3)
end
N += 1
local err
Success,err = pcall(function()
datastore:SetAsync(Player.UserId,Data)
print("Attributes Set")
local atts = Player:GetAttributes()
local att = Player:GetAttribute("SportsCar")
print(att)
end)
if err then
print(err)
end
until Success or N >= 5
end)
I also tried changing the script to take the attributes from the humanoid instead of player which is what it is being set to when the player purchases the car but this didn’t work either, nor did trying to get the AttributeChangedSignal and set the Attribute manually inside the saving script;
local players = game:GetService("Players")
local datastoreService = game:GetService("DataStoreService")
local datastore = datastoreService:GetDataStore("PlayerAttributes")
local AttributeList = {
SportsCar = {"boolean","false"},
SUV = {"boolean","false"}
}
local FromStringFunctions = {
number = tonumber,
boolean = function(var)
if var == "true" then
return true
else
return false
end
end
}
local ToStringFunctions = {
number = tostring,
boolean = function(var)
if var then
return "true"
else
return "false"
end
end,
}
players.PlayerAdded:Connect(function(Player :Player)
wait(5)
local char = Player.Character
local human = char:FindFirstChild("Humanoid")
local Data
xpcall(function()
Data = datastore:GetAsync(Player.UserId)
end, function(err)
Player:Kick("Error Loading Credentials"..err)
end)
if not Data then
Data ={}
end
for index, value in pairs(AttributeList) do
if not Data[index] then
Data[index] = FromStringFunctions[value[1]](value[2])
end
end
for index,value in pairs(Data) do
Player:SetAttribute(index,value)
print("Attributes Set")
local atts = human:GetAttributes()
local att = human:GetAttribute("SportsCar")
print(att)
human:GetAttributeChangedSignal("SportsCar"):Connect(function()
wait(2)
human:SetAttribute("SportsCar", true)
wait(4)
print("Property changed"..tostring(att))
end)
end
end)
players.PlayerRemoving:Connect(function(Player :Player)
local char = Player.Character
local human = char:FindFirstChild("Humanoid")
local Data = {}
for index,value in pairs(AttributeList) do
Data[index] = human:GetAttribute(index)
end
local Success = true
local N = 0
repeat
if not Success then
wait(0.3)
end
N += 1
local err
Success,err = pcall(function()
datastore:SetAsync(Player.UserId,Data)
print("Attributes Set")
local atts = human:GetAttributes()
local att = human:GetAttribute("SportsCar")
print(att)
end)
if err then
print(err)
end
until Success or N >= 5
end)
game:BindToClose(function()
wait(3)
end)
I’m not sure what I’m doing wrong with it but any help will be appreciated, Thanks in advance.