Can't detect the character after the player leaves

I didn’t run into any problems with saving tools, except it never saved the tool that was currently equipped while the player was leaving, because it was inside the character, not the Backpack. I’m trying to find a workaround for it.

The main problem is when I try to find the player’s character when they exit the game. It gives me this error message:

ServerScriptService.DataHandler:36: attempt to index nil with 'CharacterRemoving'

I have tried using a BoolValue to detect the equipped tool, both inside the Backpack and PlayerGui. (it surprisingly couldn’t find it either???)

Right now I’m trying to figure out if I can do this by unequipping the tool from the character. I will leave the portion of the script responsible for detecting players leaving here:

players.PlayerRemoving:Connect(function(player)
	
	player.Character.CharacterRemoving:Connect(function(character)
		character.Humanoid:UnequipTools() 
	end)
	
	local key = player.Name .. "'s inventory"
	local savedTools = {}

	local currentTools = player.Backpack:GetChildren()

	for i, v in pairs(currentTools) do
		table.insert(savedTools, v.Name)
	end	
	
	inventoryData:UpdateAsync(key, function(prev)
		print("Saved tools!")
		return savedTools
	end)	
	
end)

I swear that this code would work, if only it could consistently find the character… Any help would be appreciated.

1 Like

Maybe try this?

players.PlayerRemoving:Connect(function(player)
	
    if player.Character then
		player.Character.Humanoid:UnequipTools() 
	end
	
	local key = player.Name .. "'s inventory"
	local savedTools = {}

	local currentTools = player.Backpack:GetChildren()

	for i, v in pairs(currentTools) do
		table.insert(savedTools, v.Name)
	end	
	
	inventoryData:UpdateAsync(key, function(prev)
		print("Saved tools!")
		return savedTools
	end)	
	
end)

Also I’m pretty sure that the character gets removed once they leave the server, and I’d recommend saving with the player’s userid instead of name incase the player changes their username.

Try using SetAsync instead

also char limit

No, please use UpdateAsync it’s overall safer :)!

And I don’t think you even need the event just use

if player.Character then
player.Character:FindFirstChildOfClass("Humanoid"):UnequipTools() 
else
warn("Unable to unequip tools") 
end
if player.Character then
	player.Character.Humanoid:UnequipTools() 
end

I’m also pretty sure that this doesn’t allow to save the equipped tool consistently. I save data based on the username because I want to.

1 Like

You can probably look inside of the player.Character and check for tool objects too.

Your solution is practically identical to @flkfv 's, except it prints out the error message.

Yeah sorry I just saw it, but try to consider checking for the tools inside the character too :).

Never mind it does not make sense at all if player character does not exists.

It’s fine eversince it’s your choice to do it or not.
Also I might be wrong but I’m pretty sure that the character gets removed before the player gets removed.

UnequipTools is supposed to put tools inside the player’s backpack.

It won’t work, because the problem is that it can’t find the character. As it turns out, the character is removed before the player. Is that normal? How do I manage to save the equipped tool before the character is gone?

Hm maybe try to use another ways how to save your data maybe in some kind of intervals because like you said it can be bit wonky.

Well you can maybe save the tools when the character is removed inside a PlayerAdded event, that might work but I’m not sure.

1 Like

Tried it. Same problem.

@caviarbro Saving in intervals might still cause a tool to be missing.

I will try to implement a manual saving system instead, if this can’t work. Inconvenient, but I have to somehow manage.

Well, CharacterRemoving is not an event of the character of the player. It actually belongs to the player.

player.CharacterRemoving:Connect(function(character)
    --And the rest of the code
end)
2 Likes

Nice catch, I make the stupidest mistakes… I placed this code at the end of the PlayerAdded event, so it runs consistently now. Thanks.

1 Like