Les checkpoints sont des points de sauvegarde dans un jeu. Quand un joueur touche un checkpoint, sa position est enregistrée. Si le joueur meurt ou revient dans la partie, il réapparaît au dernier checkpoint touché.
Dans ce script, les checkpoints ne sont pas ordonnés : le joueur peut les toucher dans n’importe quel ordre.
- Comment parcourir les checkpoints dans un dossier avec une boucle
for. - Comment stocker le dernier checkpoint pour chaque joueur.
- Comment détecter quand un joueur revient dans la partie et le téléporter à son dernier checkpoint.
Préparation dans Roblox Studio

Pour tester ce script, suis ces étapes :
- Créer un dossier pour les checkpoints :
- Dans
Workspace, crée un dossier nomméCheckpointsFolder.
- Dans
- Ajouter des checkpoints :
- Ajoute plusieurs
PartdansCheckpointsFolder. - Nomme-les comme tu veux (ex:
Checkpoint1,Checkpoint2, etc.). - Place-les à différents endroits dans ton jeu.
- Ajoute plusieurs
- Ajouter le script :
- Crée un
ScriptdansServerScriptServiceet copie le code suivant. - Le script supprime automatiquement la
Baseplatepour éviter les interférences. - Si tu veux garder un sol, ajoute une
Partplate dansWorkspace.
- Crée un
Voici le script commenté pour comprendre :
-- Récupérer les services et objets nécessaires
local Players = game:GetService("Players") -- Service pour gérer les joueurs
-- Récupérer la Baseplate et le dossier des checkpoints
local baseplate = workspace:WaitForChild("Baseplate")
local checkpointsFolder = workspace:WaitForChild("CheckpointsFolder")
-- Tableau pour stocker le dernier checkpoint de chaque joueur
-- Format : playerCheckpoints[userId] = CFrame du dernier checkpoint
local playerCheckpoints = {}
-- Supprimer la Baseplate (pour éviter les interférences)
baseplate:Destroy()
-- Fonction appelée quand un personnage est ajouté (ex: quand un joueur respawn)
local function onCharacterAdded(character, userId)
-- Récupérer le dernier checkpoint du joueur
local storedCFrame = playerCheckpoints[userId]
-- Si le joueur n'a pas de checkpoint enregistré, on ne fait rien
if not storedCFrame then
return
end
-- Attendre que le HumanoidRootPart existe (partie principale du personnage)
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
-- Ajouter un petit décalage aléatoire pour éviter que les joueurs spawnent au même endroit
local offset = Vector3.new(math.random(-1, 1), 4, math.random(-1, 1))
-- Téléporter le joueur à son dernier checkpoint + décalage
humanoidRootPart.CFrame = storedCFrame + offset
end
-- Fonction appelée quand un joueur touche un checkpoint
local function onTouched(checkpoint, hit)
-- Récupérer le personnage qui a touché le checkpoint
local character = hit.Parent
-- Vérifier si c'est bien un personnage avec un Humanoid (un joueur)
if not character or not character:FindFirstChildOfClass("Humanoid") then
return
end
-- Récupérer le joueur associé au personnage
local player = Players:GetPlayerFromCharacter(character)
if not player then
return
end
-- Récupérer l'ID unique du joueur
local userId = player.UserId
-- Connecter l'événement CharacterAdded UNE SEULE FOIS par joueur
-- Cela évite de connecter plusieurs fois le même événement
if not playerCheckpoints[userId] then
player.CharacterAdded:Connect(function(newCharacter)
onCharacterAdded(newCharacter, userId)
end)
end
-- Stocker le CFrame (position + rotation) du checkpoint pour ce joueur
playerCheckpoints[userId] = checkpoint.CFrame
end
-- Parcourir tous les checkpoints dans le dossier CheckpointsFolder
for _, checkpoint in ipairs(checkpointsFolder:GetChildren()) do
-- Vérifier si l'objet est une BasePart (ex: une Part)
if not checkpoint:IsA("BasePart") then continue end
-- Configurer le checkpoint
checkpoint.Anchored = true -- Empêcher le checkpoint de bouger
checkpoint.CanCollide = true -- Permettre les collisions
checkpoint.Transparency = 0.5 -- Rendre le checkpoint semi-transparent
checkpoint.Material = Enum.Material.Neon -- Matériau Neon pour un effet lumineux
checkpoint.BrickColor = BrickColor.new("Bright blue") -- Couleur bleue vive
-- Connecter l'événement Touched pour détecter quand un joueur touche le checkpoint
checkpoint.Touched:Connect(function(hit)
onTouched(checkpoint, hit)
end)
end
Le script supprime automatiquement la Baseplate.
1. La boucle for pour parcourir les checkpoints

for _, checkpoint in ipairs(checkpointsFolder:GetChildren()) do
if not checkpoint:IsA("BasePart") then continue end
-- Configurer le checkpoint...
end
checkpointsFolder:GetChildren():- Récupère tous les enfants directs du dossier
CheckpointsFolder. - Retourne une liste de tous les objets dans ce dossier.
- Récupère tous les enfants directs du dossier
ipairs(...):- Parcourt la liste des enfants un par un.
_est une variable temporaire (non utilisée) qui représente l’index (position dans la liste).checkpointest l’objet actuel dans la boucle (ex: unePart).
if not checkpoint:IsA("BasePart") then continue end:- Vérifie si
checkpointest uneBasePart(ex: unePart). - Si ce n’est pas le cas (ex: un
Folder, unScript), on passe à l’itération suivante aveccontinue.
- Vérifie si
- Pourquoi utiliser
GetChildren?- On veut trouver tous les checkpoints dans le dossier
CheckpointsFolder. GetChildrenest plus rapide queGetDescendantscar on ne cherche que les enfants directs (pas les petits-enfants).
- On veut trouver tous les checkpoints dans le dossier
2. Stocker le checkpoint pour le joueur
local playerCheckpoints = {} -- Tableau pour stocker les checkpoints
-- Dans la fonction onTouched :
playerCheckpoints[userId] = checkpoint.CFrame
playerCheckpoints:- C’est un tableau associatif où :
- Clé =
userId(l’ID unique du joueur). - Valeur =
CFramedu dernier checkpoint touché par le joueur.
- Clé =
- C’est un tableau associatif où :
checkpoint.CFrame:- Le
CFrameest une propriété qui stocke la position et la rotation d’un objet. - Quand un joueur touche un checkpoint, on stocke son
CFramedansplayerCheckpoints[userId].
- Le
- Pourquoi utiliser
userIdcomme clé ?- Chaque joueur a un ID unique (
UserId). - Cela permet de stocker un checkpoint différent pour chaque joueur.
- Chaque joueur a un ID unique (
3. Détecter quand le joueur revient dans la partie
-- Dans la fonction onTouched :
if not playerCheckpoints[userId] then
player.CharacterAdded:Connect(function(newCharacter)
onCharacterAdded(newCharacter, userId)
end)
end
-- Fonction onCharacterAdded :
local function onCharacterAdded(character, userId)
local storedCFrame = playerCheckpoints[userId]
if not storedCFrame then return end
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local offset = Vector3.new(math.random(-1, 1), 4, math.random(-1, 1))
humanoidRootPart.CFrame = storedCFrame + offset
end
player.CharacterAdded:Connect(...):- Événement déclenché quand un joueur respawn (réapparaît après être mort ou avoir rejoint le jeu).
- On connecte une seule fois cet événement par joueur (grâce à
if not playerCheckpoints[userId]).
onCharacterAdded:- Cette fonction est appelée quand un joueur réapparaît.
- Elle téléporte le joueur à son dernier checkpoint (
storedCFrame). offset: Ajoute un petit décalage aléatoire pour éviter que plusieurs joueurs spawnent au même endroit.
WaitForChild("HumanoidRootPart"):- Attend que le
HumanoidRootPart(partie centrale du personnage) existe avant de le téléporter. - Cela évite les erreurs si le personnage n’est pas encore complètement chargé.
- Attend que le
QCM : Teste ta compréhension !
Sur la boucle for et GetChildren :
- Que fait
checkpointsFolder:GetChildren()?- a) Récupère tous les enfants directs du dossier
CheckpointsFolder. - b) Récupère tous les descendants (enfants, petits-enfants, etc.) du dossier.
- c) Supprime tous les enfants du dossier.
- a) Récupère tous les enfants directs du dossier
- Pourquoi utilise-t-on
if not checkpoint:IsA("BasePart") then continue end?- a) Pour ignorer les objets qui ne sont pas des
BasePart(ex: desFolder). - b) Pour supprimer les checkpoints.
- c) Pour changer la couleur des checkpoints.
- a) Pour ignorer les objets qui ne sont pas des
- Que contient la variable
checkpointdans la bouclefor?- a) Un objet (ex: une
Part) dans le dossierCheckpointsFolder. - b) Un nombre.
- c) Un joueur.
- a) Un objet (ex: une
Sur le stockage des checkpoints :
- À quoi sert
playerCheckpoints[userId] = checkpoint.CFrame?- a) Stocker la position et la rotation du checkpoint pour un joueur.
- b) Supprimer le checkpoint.
- c) Changer la taille du checkpoint.
- Pourquoi utilise-t-on
userIdcomme clé dansplayerCheckpoints?- a) Parce que chaque joueur a un ID unique, ce qui permet de stocker un checkpoint différent pour chaque joueur.
- b) Parce que c’est plus rapide.
- c) Parce que c’est obligatoire.
- Que fait
playerCheckpoints[userId]siuserIdn’existe pas dans le tableau ?- a) Retourne
nil. - b) Crée une erreur.
- c) Retourne
0.
- a) Retourne
Sur la détection du retour du joueur :
- À quoi sert
player.CharacterAdded:Connect(...)?- a) Exécuter une fonction quand un joueur réapparaît dans la partie.
- b) Créer un nouveau personnage.
- c) Supprimer le personnage.
- Pourquoi utilise-t-on
WaitForChild("HumanoidRootPart")?- a) Pour attendre que le
HumanoidRootPartexiste avant de le téléporter. - b) Pour supprimer le
HumanoidRootPart. - c) Pour changer la couleur du personnage.
- a) Pour attendre que le
- Que fait
humanoidRootPart.CFrame = storedCFrame + offset?- a) Téléporte le joueur à son dernier checkpoint avec un petit décalage aléatoire.
- b) Fait grandir le joueur.
- c) Supprime le joueur.
- Pourquoi ajoute-t-on un
offsetaléatoire ?- a) Pour éviter que plusieurs joueurs spawnent exactement au même endroit.
- b) Pour rendre le jeu plus difficile.
- c) Pour changer la taille du joueur.
Idées pour aller plus loin
1. Ajouter un effet visuel aux checkpoints
- Objectif : Faire clignoter les checkpoints quand un joueur les touche.
2. Ajouter un son quand un checkpoint est touché
- Objectif : Jouer un son quand un joueur touche un checkpoint.
