Made this script so that when a player joins their data is loaded and gui updates depending on the data. But only some of the gui updates, I have checked the data of a player and it is correct what is wrong?
script (local)
BTW this is only a part of the script. Also my variable are very much correct, so dont worry about those.
EquippedTP.Changed:Connect(function()
if EquippedTP.Value == true then
EquipButtonTP.Text = "Equipped"
elseif EquippedTP.Value == false then
EquipButtonTP.Text = "Equip"
end
end)
EquippedGH.Changed:Connect(function()
if EquippedGH.Value == true then
EquipButtonGH.Text = "Equipped"
elseif EquippedGH.Value == false then
EquipButtonGH.Text = "Equip"
end
end)
EquippedWH.Changed:Connect(function()
if EquippedWH.Value == true then
EquipButtonWH.Text = "Equipped"
elseif EquippedWH.Value == false then
EquipButtonWH.Text = "Equip"
end
end)
EquippedIH.Changed:Connect(function()
if EquippedIH.Value == true then
EquipButtonIH.Text = "Equipped"
elseif EquippedIH.Value == false then
EquipButtonIH.Text = "Equip"
end
end)
I’m assuming these are BoolValues inside of a folder of the player instance. How are these values being set on the server when the player first joins?
My assumption is that some of the values are being set before the client loads and therefore the Changed event is not triggered for that particular BoolValue. Have you tried just updating the values outside of the Changed events as well? Like so:
EquippedTP.Changed:Connect(function()
if EquippedTP.Value == true then
EquipButtonTP.Text = "Equipped"
elseif EquippedTP.Value == false then
EquipButtonTP.Text = "Equip"
end
end)
EquippedGH.Changed:Connect(function()
if EquippedGH.Value == true then
EquipButtonGH.Text = "Equipped"
elseif EquippedGH.Value == false then
EquipButtonGH.Text = "Equip"
end
end)
EquippedWH.Changed:Connect(function()
if EquippedWH.Value == true then
EquipButtonWH.Text = "Equipped"
elseif EquippedWH.Value == false then
EquipButtonWH.Text = "Equip"
end
end)
EquippedIH.Changed:Connect(function()
if EquippedIH.Value == true then
EquipButtonIH.Text = "Equipped"
elseif EquippedIH.Value == false then
EquipButtonIH.Text = "Equip"
end
end)
EquipButtonTP.Text = EquippedTP.Value and "Equipped" or "Equip" -- This is equivalent to what you have inside of the Changed event
EquipButtonGH.Text = EquippedGH.Value and "Equipped" or "Equip"
EquipButtonWH.Text = EquippedWH.Value and "Equipped" or "Equip"
EquipButtonIH.Text = EquippedIH.Value and "Equipped" or "Equip"
Ok I tried it out and realized that only the first two work because they load in first, I can confirm this because I put a wait() before your addition and it worked, so I think I will do something like onCharacterLoaded or PlayerJoined and put your addition inside so if my part does not work, yours will act as a backup system. Did that make sense?
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Event = ReplicatedStorage.Equipped
local Players = game:GetService("Players")
Event.OnServerEvent:Connect(function(Player, HookType)
local GHOwned = Player:WaitForChild("GoldenHook"):WaitForChild("Owned")
local TPOwned = Player:WaitForChild("TPose"):WaitForChild("Owned")
local WHOwned = Player:WaitForChild("WoodenHook"):WaitForChild("Owned")
local IHOwned = Player:WaitForChild("InvisibleHook"):WaitForChild("Owned")
local TP = Player:WaitForChild("TPose"):WaitForChild("Equipped")
local GH = Player:WaitForChild("GoldenHook"):WaitForChild("Equipped")
local WH = Player:WaitForChild("WoodenHook"):WaitForChild("Equipped")
local IH = Player:WaitForChild("InvisibleHook"):WaitForChild("Equipped")
local Character = Player.Character
if HookType == "TP" then
if TPOwned.Value == true then
TP.Value = not TP.Value
end
elseif HookType == "GH" then
if GHOwned.Value == true then
GH.Value = not GH.Value
end
elseif HookType == "WH" then
if WHOwned.Value == true then
WH.Value = not WH.Value
end
elseif HookType == "IH" then
if IHOwned.Value == true then
IH.Value = not IH.Value
end
end
end)
--//Services
local Players = game:GetService("Players")
local DataStoreService = game:GetService("DataStoreService")
--//Variables
local dataStore = DataStoreService:GetDataStore("MyDataStore")
--//Functions
local function saveData(player)
local tableToSave = {
Coins = player.leaderstats.Coins.Value,
OwnedGH = player.GoldenHook.Owned.Value,
EquippedGH = player.GoldenHook.Equipped.Value,
OwnedTP = player.TPose.Owned.Value,
EquippedTP = player.TPose.Equipped.Value,
OwnedUS = player.UpsideDown.Owned.Value,
EquippedUS = player.UpsideDown.Equipped.Value,
OwnedWH = player.WoodenHook.Owned.Value,
EquippedWH = player.WoodenHook.Equipped.Value,
EquippedIH = player.InvisibleHook.Equipped.Value,
OwnedIH = player.InvisibleHook.Owned.Value
}
local success, errorMessage = pcall(function()
dataStore:SetAsync(player.UserId, tableToSave)
end)
if success then -- If the data has been saved
print("Data has been saved!")
else -- Else if the save failed
print("Data hasn't been saved!")
warn(errorMessage)
end
end
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
--//Coins//--
local Coins = Instance.new("IntValue")
Coins.Name = "Coins"
Coins.Parent = leaderstats
--//InvisibleHook//--
local InvisibleHook = Instance.new("Folder")
InvisibleHook.Name = "InvisibleHook"
InvisibleHook.Parent = player
local OwnedIH = Instance.new("BoolValue")
OwnedIH.Name = "Owned"
OwnedIH.Parent = InvisibleHook
local EquippedIH = Instance.new("BoolValue")
EquippedIH.Name = "Equipped"
EquippedIH.Parent = InvisibleHook
--//WoodenHook//--
local WoodenHook = Instance.new("Folder")
WoodenHook.Name = "WoodenHook"
WoodenHook.Parent = player
local OwnedWH = Instance.new("BoolValue")
OwnedWH.Name = "Owned"
OwnedWH.Parent = WoodenHook
local EquippedWH = Instance.new("BoolValue")
EquippedWH.Name = "Equipped"
EquippedWH.Parent = WoodenHook
--//UpsideDown//--
local UpsideDown = Instance.new("Folder")
UpsideDown.Name = "UpsideDown"
UpsideDown.Parent = player
local OwnedUS = Instance.new("BoolValue")
OwnedUS.Name = "Owned"
OwnedUS.Parent = UpsideDown
local EquippedUS = Instance.new("BoolValue")
EquippedUS.Name = "Equipped"
EquippedUS.Parent = UpsideDown
--//Golden Hook//--
local GoldenHook = Instance.new("Folder")
GoldenHook.Name = "GoldenHook"
GoldenHook.Parent = player
local OwnedGH = Instance.new("BoolValue")
OwnedGH.Name = "Owned"
OwnedGH.Parent = GoldenHook
local EquippedGH = Instance.new("BoolValue")
EquippedGH.Name = "Equipped"
EquippedGH.Parent = GoldenHook
--//TPose//--
local TPose = Instance.new("Folder")
TPose.Name = "TPose"
TPose.Parent = player
local OwnedTP = Instance.new("BoolValue")
OwnedTP.Name = "Owned"
OwnedTP.Parent = TPose
local EquippedTP = Instance.new("BoolValue")
EquippedTP.Name = "Equipped"
EquippedTP.Parent = TPose
--//Other//--
local Folder4 = Instance.new("Folder")
Folder4.Name = "NumberOfHooks"
Folder4.Parent = player
local IntValue2 = Instance.new("IntValue")
IntValue2.Name = "Amount"
IntValue2.Parent = Folder4
local data = nil
local success, errorMessage = pcall(function()
data = dataStore:GetAsync(player.UserId)
end)
if success and data then
Coins.Value = data.Coins
OwnedGH.Value = data.OwnedGH
OwnedTP.Value = data.OwnedTP
EquippedTP.Value = data.EquippedTP
EquippedGH.Value = data.EquippedGH
EquippedUS.Value = data.EquippedUS
OwnedUS.Value = data.OwnedUS
EquippedIH.Value = data.EquippedIH
OwnedIH.Value = data.OwnedIH
EquippedWH.Value = data.EquippedWH
OwnedWH.Value = data.OwnedWH
else
print("The player has no data!") -- The default will be set to 0
end
end)
Players.PlayerRemoving:Connect(saveData)
game:BindToClose(function() -- When the server shuts down
for _, player in Players:GetPlayers() do -- Loop through all the players
saveData(player)
end
end)
You should use a module that stores the player data.
About your issue, you could just launch a RemoteEvent after a value is changed, then do what ProgrammingRottie did:
RemoteFunction.OnClientEvent:Connect(function()
EquipButtonTP.Text = EquippedTP.Value and "Equipped" or "Equip"
EquipButtonGH.Text = EquippedGH.Value and "Equipped" or "Equip"
EquipButtonWH.Text = EquippedWH.Value and "Equipped" or "Equip"
EquipButtonIH.Text = EquippedIH.Value and "Equipped" or "Equip"
end)
You could also wrap these connections as the issue might be that these are not loading for the client, using coroutine.wrap() (so the connections wouldn’t need to wait for the previous connection to start), but this would take a lot of space on the script
coroutine.wrap(function()
EquippedTP.Changed:Connect(function()
if EquippedTP.Value == true then
EquipButtonTP.Text = "Equipped"
elseif EquippedTP.Value == false then
EquipButtonTP.Text = "Equip"
end
end)
end)()
coroutine.wrap(function()
EquippedGH.Changed:Connect(function()
if EquippedGH.Value == true then
EquipButtonGH.Text = "Equipped"
elseif EquippedGH.Value == false then
EquipButtonGH.Text = "Equip"
end
end)
end)()
coroutine.wrap(function()
EquippedWH.Changed:Connect(function()
if EquippedWH.Value == true then
EquipButtonWH.Text = "Equipped"
elseif EquippedWH.Value == false then
EquipButtonWH.Text = "Equip"
end
end)
end)()
coroutine.wrap(function()
EquippedIH.Changed:Connect(function()
if EquippedIH.Value == true then
EquipButtonIH.Text = "Equipped"
elseif EquippedIH.Value == false then
EquipButtonIH.Text = "Equip"
end
end)
end)()
My suggestion is using RemoteEvents and managing data inside a module instead.
Then you can send the data through the server and manage the data with ease
Don’t depend on instances and always manage data inside scripts and/or modules
What do I tie the remote event to? Also how would I use this module script, I dont want you to waste your time teaching a scripting newbie so if you could refer me to a page or smth that would be great.
You should tie the event to whenever updates the data inside a server-side script.
To use the module, it’s pretty easy. It’s like working with a table, but other scripts with the same level (in this case, all server scripts) would have access to it.
This would also work with client scripts, but the data is not replicated, so if you set something in the server-side, client won’t see it. This is good to avoid exploiters trying to modify the data.
Now, to retrieve a module, you need to include a variable with value require().
Inside the require(), you will have to put the instance. It’s the best option to put the module below the same main script, so you can only do local module = require(script.ModuleScript).
Inside the module script you will see this default code:
local module = {}
return module
So, you can set the module to make some data key for you, which would store player’s data.
local module = {}
module.PlayerData = {}
--[[ You can add the data and make the index the same as the PlayerId, so it would be like this:
module.PlayerData = {
[12345678] = {} -- Data Table
}
12345678 would be the player's user id.
]]
return module
Why don’t you just stall the datastore load so there is an actual change … or have a script to set up off the datastore separate from the changed script.
if Module.PlayerData[UserId] then
print('Player has '..Module.PlayerData[UserId].Coins..' coins!')
end
Useful to save inside DataStore tables, you just have to:
local DataStore = game:GetService('DataStoreService'):GetDataStore('A')
if Module.PlayerData[UserId] then
local Saved, Nope = pcall(function()
DataStore:SetAsync(UserId, Module.PlayerData[UserId])
end)
if Saved then
print('Saved')
else
warn(Nope)
end
end
You can get it from the UserId, you asign that index to the module, and the value will be the player’s table, which you can get when the player joins