I’m trying to get the Player.Character inside the Players.PlayerRemoving to get the value of an instance that is parented to the Character and save the data to a DataStore.
However, the Players.PlayerRemoving only returns the Player instance, but not the Player.Character
(The following code is in the same server-side script)
Players.PlayerAdded:Connect(function(Player)
-- detect when a player join and load his data
end)
Players.PlayerRemoving:Connect(function(Player)
-- here I need to get the Character to save the Value of..
-- ..an Instance parented to it
print(Player) -- returns the Player Instance
print(Player.Character) -- returns nil
end)
I tried using Player.CharacterRemoving, but it don’t work inside the Players.PlayerRemoving (this is expected, nothing abnormal)
Players.PlayerRemoving:Connect(function(Player)
local Char = nil
Player.CharacterRemoving:Connect(function(Character)
-- this never executes
print(Character)
Char = Character
end)
print(Char) -- returns nil
end)
I need to get the Character only when the player is leaving the game, not on all times the Character loads. How can I achieve that?
Edit: I also need to get the Character position when leaving.
By the time Players.PlayerRemoving fires, the character has already been destroyed, so you can’t access it at all, unless you have a previous reference to it. Try either parenting the value to the player and modifying it through there, or just listening for CharacterRemoving in a separate connection.
Thank you for the reply. Parenting the value to the Player would be a solution to the first problem.
However, I also need to get the Character.HumanoidRootPart.Position to check if there are players on a certain team near him when he leaves. So I need the Character instance to get the HumanoidRootPart.Position.
If I listen to CharacterRemoving on a separate connection, I would need to detect if the Player is acctually leaving or if the Charater is just being loaded (respawned). If this is the best solution, how can I do this?
local LastPosition = {};
game:GetService('Players').PlayerAdded:Connect(function(Player)
Player.CharacterRemoving:Connect(function(Char)
LastPosition[Player] = Char.HumanoidRootPart.Position;
end)
end)
game:GetService('Players').PlayerRemoving:Connect(function(Player)
local lastCharacterPosition = LastPosition[Player];
end)
Edit: Unsure of the exact order of events, so may be worth checking to see if Player.Character exists first (and then using that value directly) before resorting to ‘LastPosition’, as if the PlayerRemoving is called first then the last position will be wherever the player died in their previous life. You could also just make it really simple and add a task.wait() or debounce before retrieving LastPosition[Player] to ensure that any sort of delay in the CharacterRemoving process doesn’t cause it to execute after PlayerRemoving.
Player.CharacterRemoving:Connect(function()
task.wait(10)
if (not workspace:FindFirstChild(Player.Name)) then
print("Player left the game.")
end
end)
Since the character gets loaded on the server, this should work for lag as well. Otherwise, you can set CharacterAutoLoads to false and load the character manually on Humanoid.Died event.
As for logging the player’s previous position pretty much all use cases for that could be superseded by attributes. What is your case?
Yes, exactly. I’m working on a type of anti-combat-logging. However, I also need to get the player position, not only the value (that could be stored in the Player Instance). So I need the Character to get its position on the workspace before it leaves.
As for logging the player’s previous position pretty much all use cases for that could be superseded by attributes. What is your case?
My case is: I need to check if there was a cop (players on the Police team) near the leaving player to check if he is trying to avoid arrest by leaving the game before he get cuffed by the cop near him.
Code (click to open)
if Player.leaderstats.WantedLevel.Value > 0 then
local IsDetained = Player:FindFirstChild('IsDetained')
if IsDetained then
-- mark player as escapee (left the game as detained)
else
for _, Plr in pairs(Players:GetChildren()) do
if Plr.Team == Teams["Police"] or Plr.Team == Teams["Sheriff"] then
-- here I need to get the Leaving Character position
local LeavingPos = Character.HumanoidRootPart.Position
local CurrentPlrPos = Plr.Character.HumanoidRootPart.Position
if (LeavingPos - CurrentPlrPos).magnitude <= 15 then
--mark player as escapee (left the game while there was a cop near him)
end
end
end
end
end
What do you mean by “pretty much all use cases for that could be superseded by attributes”? Thanks.
Thank you, this might solve the problem, Additionally, @1234koip reply add a task.wait(10) to remove the character from the table and avoid lag and optimize the code.
Ill just wait the answer from him on my new reply and maybe mark this as a solution.