When someone is about to die without food (in game), they may leave. im trying to prevent that with a saving health script so they cant chicken out on their death and lose their money.
The problem is that the saved health isnt applying to the character or not saving.
when the game.Players.PlayerRemoving event fires the character has already been destroyed so
player.Character will equal to nil
so to fix this problem you will have to use the CharacterAdded event and save a reference of the character into a table or something then when they leave use the reference in the table to get the health
local characters = {}
game.Players.PlayerAdded:connect(function(player)
player.CharacterAdded:Connect(function(character)
characters[player] = character -- save the new character into the characters table
end)
end
game.Players.PlayerRemoving:connect(function(player)
if characters[player] == nil then return end
print(characters[player].Humanoid.Health)
characters[player] = nil -- set to nil so we don't get a memory leak
end
I also wouldn’t recommend saving the players health every time it changes. Since you’re saving it when they leave, there’s no point saving in between. Otherwise you’re going to hit the setasync request limit very quickly which could also cause the datastore not to save
Like 5uphi said, I have my script in were saving it when they leave, it requests the character’s health (which is gone because they already left) so making it so when they leave may be a good idea if it wasn’t requesting a nonexistent character.
game.Players.PlayerRemoving:connect(function(player)
ds:SetAsync(player.UserId, player.Character.Humanoid.Health) -- all of this is broken.
end)
You could try recording the player’s health when it changes and store that, then when they leave retrieve the value’s data and delete it.
I’m not sure if CharacterRemoving works as they leave, but you could try it as an alternative to saving health on change. (If it does, of course, make sure you don’t update their health to 0 on join)
local Game = game
local Players = Game:GetService("Players")
local DataStoreService = Game:GetService("DataStoreService")
local HealthStore = DataStoreService:GetDataStore("HealthStore")
local Healths = {}
local function OnPlayerAdded(Player)
local function OnCharacterAdded(Character)
local function OnHumanoidHealthChanged(Health)
Healths[Player] = Health
end
local Humanoid = Character:FindFirstChildOfClass("Humanoid") or Character:WaitForChild("Humanoid", 10)
if Humanoid then Humanoid.HealthChanged:Connect(OnHumanoidHealthChanged) end
end
Player.CharacterAdded:Connect(OnCharacterAdded)
local Success, Result = pcall(function() return HealthStore:GetAsync(Player.UserId) end)
if not Success then warn(Result) return end
if not Result then return end
local Character = Player.Character or Player.CharacterAdded:Wait()
local Humanoid = Character:FindFirstChildOfClass("Humanoid") or Character:WaitForChild("Humanoid", 10)
if Humanoid then Humanoid.Health = Result end
end
local function OnPlayerRemoving(Player)
if not Healths[Player] then return end
local Success, Result = pcall(function() return HealthStore:SetAsync(Player.UserId, Healths[Player]) end)
if not Success then warn(Result) end
Healths[Player] = nil
end
Players.PlayerAdded:Connect(OnPlayerAdded)
Players.PlayerRemoving:Connect(OnPlayerRemoving)
You may need to include ‘BindToClose’ for studio testing but this is working on my end.