How to properly handle teleporting to a checkpoint after death

When I was making a checkpoint system for my game I had a few timing problems with the teleporting of the the player after death.
The Humanoid.Died script signal gets activated when the health reaches 0 so I was confused at fiest… But then I realised that I need to wait until the player respawns and then wait for a small time so that the teleportation always happens after the teleportation roblox does.

This seems to work fine but I am worried that when the server slows down the respawn teleportation will happen before my script will teleport the player to correct location. So I am asking… Is there a proper way of teleporting the player after they die?

2 Likes

You could bind it to character respawn instead of character death

Just bind the teleport function to Player.CharacterAdded

1 Like

And there Is no need for delay?

No, but you may have to wait until the HumanoidRootPart gets added into the character using a :WaitForChild()

2 Likes

Player.CharacterAdded => character:MoveTo(Vector3)

1 Like

Unneeded, CharacterAdded is called when all of the humanoid’s baseparts are added. (Torso, head, etc)

1 Like

I still have to add a delay in order for it to work
This is propably because character added gets triggered before the player has teleported to the correct spawnlocation.
If you guys know how to check if the player has teleported or just override the respawning function or something like that pls help

Hi!

I created my own checkpoint script a while ago, I edited some of the code for you. :slight_smile:

-- CheckpointHandler Script
local Players = game:GetService("Players")
local Checkpoints = workspace:WaitForChild("Checkpoints")
local CheckpointSkip = false
local Debounce = {}
for _, Checkpoint in pairs(Checkpoints:GetChildren()) do
	Checkpoint.Touched:Connect(function(Part)
		local Humanoid = Part.Parent:FindFirstChildWhichIsA("Humanoid")
		if Humanoid and Humanoid.Health > 0 then
			local Player = Players:GetPlayerFromCharacter(Part.Parent)
			if not Debounce[Player.Name] then
				Debounce[Player.Name] = true
				local FOL_Score = Player:FindFirstChild("leaderstats")
				if FOL_Score then
					local Current_Checkpoint = FOL_Score:FindFirstChild("Checkpoint")
					if Current_Checkpoint then
						if tonumber(Checkpoint.Name) > Current_Checkpoint.Value then
							if CheckpointSkip then
								Current_Checkpoint.Value = tonumber(Checkpoint.Name)
							elseif Current_Checkpoint.Value + 1 == tonumber(Checkpoint.Name) then
								Current_Checkpoint.Value = tonumber(Checkpoint.Name)
							end
						end
					end
				end
				Debounce[Player.Name] = nil
			end
		end
	end)
end
--PlayerAdded Server script
-- require gameServices
local serverScriptService = game:GetService("ServerScriptService")
local replicatedStorage = game:GetService("ReplicatedStorage")

local Checkpoints = workspace:WaitForChild("Checkpoints")
local defaultCheckpoint = 1
local spawnDelay = 3
-- when players join function
game:GetService("Players").PlayerAdded:Connect(function(player)
	local FOL_Score = Instance.new("Folder")
	FOL_Score.Name = "leaderstats"
	local Score_CHECKPOINT = Instance.new("IntValue")
	Score_CHECKPOINT.Name = "Checkpoint"
	Score_CHECKPOINT.Value = defaultCheckpoint
	Score_CHECKPOINT.Parent = FOL_Score

	player.CharacterAdded:Connect(function(Character)
		local HumanoidRootPart = Character:WaitForChild("HumanoidRootPart")
		local Humanoid = Character:WaitForChild("Humanoid")
		Humanoid.Died:Connect(function()
			task.wait(spawnDelay) -- You can remove this, if you want them to spawn instantly
			player:LoadCharacter()
		end)

		repeat wait() until Character.Parent
		local Checkpoint = Checkpoints[Score_CHECKPOINT.Value]
		HumanoidRootPart.CFrame = (Checkpoint.CFrame + Vector3.new(0,-Checkpoint.Size.Y/2 + 5,0))
	end)
end)

Please let me know if you get any errors, haven’t tested it after modifying it for you. :slight_smile:

1 Like