An event that fires when Player:LoadCharacter() is called but not when Humanoid.Died fires?

Please read carefully…

What is the best way to check if a player has respawned (due to Player:LoadCharacter()) but not including when the player dies?
In other words: I want an event that fires when Player:LoadCharacter() is called, but not when Humanoid.Died fires, so using CharacterAdded won’t work.

My current solution at the moment:
To ‘mimic’ the event described above, I am using the CharacterAdded event to detect when the character loads. Then, to detect that this was due to LoadCharacter() rather than the player dying, I have a Humanoid.Died event that fires if the player dies. If Humanoid.Died is not fired too, then I know that the player was respawned, and not killed.

Is there a better way of achieving this?

Context: I have multiple ways a player can be respawned by different systems in my game so using events is the best way for a system to know if a player respawns. I could fire my own event whenever I call Player:LoadCharacter() but… I’m looking for a lazier solution so I can use LoadCharacter() more freely.

1 Like

This is probably what you meant, but yeah:

local players = game:GetService('Players')
players.PlayerAdded:Connect(function(player)
	player.CharacterRemoving:Connect(function(character)
		local humanoid = character:FindFirstChild('Humanoid')
		if humanoid and humanoid.Health > 0 then
			humanoid = nil
			player.CharacterAdded:Wait()
			print('LoadCharacter fired for: '..player.Name)
		end
	end)
end)

I don’t think there’s a built-in way to detect that for some reason.

Although alternatively, you could just fire a remote/bindable whenever you run LoadCharacter.

3 Likes

Thanks! I think I prefer your solution. However, there is a problem…

I believe CharacterAdded:Wait() can block infinitely if CharacterRemoving is fired due to the player leaving. This is how I fixed it:

player.CharacterRemoving:Connect(function(character)
	local humanoid = character:FindFirstChild('Humanoid')
	if humanoid and humanoid.Health > 0 then
		humanoid = nil
		
		local characterAdded = false
		local conn = player.CharacterAdded:Connect(function() characterAdded = true end)
		
        -- Wait until character is added or until player leaves:
		repeat wait(0.1) until characterAdded or not Players:FindFirstChild(player.Name)
		conn:Disconnect()
		conn = nil
		
		if not characterAdded then return end -- player left
		print('LoadCharacter fired for: '..player.Name)
	end
end)

Alternatively: assuming that PlayerRemoving fires before CharacterRemoving, I guess you could break the CharacterRemoving connection when the player leaves (if there is enough time to do this??), but I couldn’t find a definitive answer on this (What fires first CharacterRemoving or PlayerRemoving?, PlayerRemoving executes before CharacterRemoving) so I believe the above code is the safest option.

2 Likes