Catégories
Jeu vidéo ROBLOX ROBLOX-NIVEAU02

Boost temporaire

À quoi sert ce script ?

Ce script permet au joueur d’appuyer sur une touche (F) pour obtenir un boost temporaire de vitesse et de saut pendant quelques secondes, avec une énergie limitée qui se réduit à chaque utilisation, affichée sous forme de barre.

Pourquoi ce script doit être un LocalScript et pas un script serveur

1. Détection des touches du clavier

UserInputService.InputBegan (qui détecte l’appui sur F) ne fonctionne que côté client. Le serveur ne « voit » pas directement quelle touche un joueur appuie sur son clavier — seul l’ordinateur du joueur (le client) peut détecter ça. Si ce script était sur le serveur, la détection de la touche ne fonctionnerait tout simplement pas.

2. Réactivité et fluidité

Un LocalScript s’exécute directement sur l’ordinateur du joueur, sans attendre d’aller-retour réseau avec le serveur. Le chrono et le boost réagissent donc instantanément, sans latence perceptible.

3. Affichage de l’interface (GUI)

Modifier un TextLabel ou la taille d’une barre (energy.Size) dans la PlayerGui doit se faire depuis un LocalScript : c’est l’interface personnelle de ce joueur, elle ne concerne que son écran à lui.

⚠️ Attention cependant : comme ce script est entièrement côté client, un joueur malveillant pourrait potentiellement le modifier pour tricher (boost infini, énergie illimitée…). Dans un vrai jeu, il faudrait que le serveur vérifie et valide réellement les changements de vitesse/saut, plutôt que de faire une confiance totale au client. Ce script convient pour l’affichage et le confort, mais une version « anti-triche » demanderait une communication avec un script serveur.

Pourquoi utiliser des CONSTANTES

EN MAJUSCULES (TIMELAPS, SPEEDMAX, JUMPMAX…)

  1. Convention de lisibilité : en programmation, écrire un nom de variable entièrement en majuscules est une convention largement utilisée pour signaler « ceci est une constante de configuration, une valeur qui ne doit jamais changer pendant l’exécution du script ». Ça permet, en un coup d’œil, de distinguer les réglages (en haut du script) des variables qui évoluent pendant le jeu (energyLevel, startime…).
  2. Facilité de modification : toutes les valeurs importantes sont regroupées au même endroit, en haut du script. Si tu veux changer la durée du boost ou la touche utilisée, tu modifies une seule ligne, sans devoir chercher dans tout le code où cette valeur est utilisée.
  3. Évite les « nombres magiques » : sans constante, on verrait des 50, 70, 6 disséminés dans le code sans savoir à quoi ils correspondent. Avec SPEEDMAX = 50, le nom explique immédiatement le rôle du nombre.

Pourquoi RunService.Heartbeat plutôt qu’une boucle while ... do wait() end

Le problème d’une boucle while avec wait()

-- ❌ Mauvaise pratique
while true do
	wait()
	-- code du chrono
end
  1. Bloque le thread : une boucle infinie s’exécute en continu et occupe le script en permanence, même quand il n’y a rien à faire.
  2. Timing imprécis : wait() ne garantit pas un délai exact — il peut varier légèrement selon la charge du jeu, ce qui rend le chrono moins précis.
  3. Difficile à arrêter proprement : il faut gérer soi-même une condition de sortie, et un oubli peut bloquer le script indéfiniment.

Pourquoi Heartbeat est meilleur

  1. Synchronisé avec le moteur du jeu : RunService.Heartbeat se déclenche automatiquement à chaque frame, juste après les calculs de physique — c’est le rythme naturel du jeu (environ 60 fois par seconde), donc le chrono reste fluide et précis.
  2. Pas de blocage : contrairement à une boucle while, Heartbeat:Connect(...) ne bloque jamais le reste du script — le code continue de s’exécuter normalement en parallèle.
  3. Gestion automatique : pas besoin de gérer soi-même l’arrêt de la boucle ; la fonction ne fait simplement rien (return immédiat) tant que startime est nil, sans gaspiller de ressources inutiles.
  4. Standard de l’industrie : c’est la méthode recommandée par Roblox pour tout ce qui doit se mettre à jour en continu (chronos, animations personnalisées, barres de vie…).

QCM pour vérifier la compréhension

1. Pourquoi ce script doit-il être un LocalScript et non un script serveur ?
A. Parce que les LocalScripts sont plus rapides à écrire
B. Parce que la détection des touches du clavier (InputBegan) ne fonctionne que côté client
C. Parce que Roblox interdit les scripts serveur sur les touches
D. Ça n’a aucune importance, les deux fonctionneraient pareil

2. Que signifie écrire une variable EN MAJUSCULES comme SPEEDMAX ?
A. Que la variable est plus rapide à lire par l’ordinateur
B. Que c’est une convention indiquant qu’il s’agit d’une constante de configuration
C. Que la variable est obligatoirement un nombre
D. Que la variable est visible par tous les scripts du jeu

3. Quel est le principal problème d’une boucle while true do wait() end pour gérer un chrono ?
A. Elle ne fonctionne pas du tout sur Roblox
B. Elle est difficile à écrire
C. Son timing est moins précis et elle bloque le thread en continu
D. Elle ne peut pas afficher de texte

4. Que fait RunService.Heartbeat ?
A. Il vérifie le rythme cardiaque du joueur
B. Il exécute une fonction automatiquement à chaque frame du jeu
C. Il redémarre le script à chaque respawn
D. Il détecte les touches du clavier

5. Pourquoi regrouper tous les réglages (TIMELAPS, SPEEDMAX, JUMPMAX…) en haut du script ?
A. Pour que le script soit plus court
B. Pour faciliter la modification des paramètres à un seul endroit, sans chercher dans tout le code
C. Parce que Roblox l’exige
D. Pour que le jeu se charge plus vite

6. Quel est le risque de sécurité mentionné concernant ce LocalScript ?
A. Il pourrait faire planter le jeu
B. Un joueur malveillant pourrait le modifier pour tricher (énergie infinie, boost permanent)
C. Il consomme trop de mémoire
D. Il ne fonctionne que sur mobile

7. Que se passe-t-il concrètement si on remplace Heartbeat par une boucle while wait() do dans ce script ?
A. Rien ne change, c’est strictement identique
B. Le chrono pourrait être légèrement moins précis et le code moins optimisé, bien que fonctionnellement proche
C. Le boost ne fonctionnerait plus du tout
D. Le jeu planterait immédiatement

Crée cette structure d’UI pour la barre d’énergie et le compteur du boost :

Le ScreenGui possède une propriété ResetOnSpawn, qui vaut true par défaut. Quand elle est activée :

  • À chaque respawn, Roblox détruit le ScreenGui actuel dans la PlayerGui et le recrée à neuf depuis sa version originale dans StarterGui.
  • Toutes les modifications faites par script sont donc perdues, et la barre d’énergie revient à sa taille définie dans les Properties de Studio.

Solution

Dans l’Explorer, sélectionne ton ScreenGui et décoche/mets à false la propriété ResetOnSpawn :

Crée un LocalScript sous StarterPlayerScripts

Sous StarterPlayerScripts

Le script s’exécute dès la connexion du joueur, souvent avant même que le personnage n’existe dans le jeu (player.Character vaut alors nil, car le perso n’a pas encore spawn).

Sous StarterCharacterScripts

Le script est recréé et réexécuté à chaque respawn du personnage.

Dans notre cas, nous avons besoin de garder les informations sur le joueur après un respawn, crée donc un LocalScript sous StarterPlayerScripts :

-- Récupération des services
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")

-- Paramètrage du service
local TIMELAPS = 6
local SPEEDMAX = 50
local JUMPMAX = 70
local TOUCHBOOST = Enum.KeyCode.F
local ENERGY_COST = 0.1

-- Récupération du player et des écrans
local player = Players.LocalPlayer

-- La PlayerGui et son contenu ne sont PAS détruits au respawn : on les récupère une seule fois
local playerGui = player:WaitForChild("PlayerGui")
local screenGui = playerGui:WaitForChild("ScreenGui")

-- Penser à modifier la propriété suivante dans ROBLOX STUDIO screenGui.ResetOnSpawn = false
local chrono = playerGui:WaitForChild("ScreenGui"):WaitForChild("Frame"):WaitForChild("ChronoBoost")
local energy = playerGui:WaitForChild("ScreenGui"):WaitForChild("Frame"):WaitForChild("Energy")
local info = energy:WaitForChild("Frame"):WaitForChild("InfoLabel")

-- Initialisation des variables au lancement du script
local humanoid, jumpHeight, walkSpeed
local energyLevel = 1
local startime = nil

-- Initialisation de l'affichage de la barre de puissance
info.Text = "Press " .. TOUCHBOOST.Name .. " to boost for 3 seconds (Energy " .. math.floor(ENERGY_COST * 100) .. "%)"
chrono.Visible = false

-- Formatage du temps restant en seconde et dixième de seconde
local function formatTime(t)
	local seconds = math.floor(t % 60)
	local tenths = math.floor((t * 10) % 10)
	return string.format("%02d.%d", seconds, tenths)
end

-- Chargement du player
local function onCharacterAdded(character)
	humanoid = character:WaitForChild("Humanoid")
	jumpHeight = humanoid.JumpHeight
	walkSpeed = humanoid.WalkSpeed
	startime = nil
end

player.CharacterAdded:Connect(onCharacterAdded)
if player.Character then
	onCharacterAdded(player.Character)
end

-- Récupération de la touche du clavier pour actionner le boost
local function onKeyPress(input, gameProcessed)
	if gameProcessed or startime or not humanoid then return end
	if input.KeyCode ~= TOUCHBOOST then return end
	if energyLevel < ENERGY_COST then return end

	humanoid.JumpHeight = JUMPMAX
	humanoid.WalkSpeed = SPEEDMAX
	--energyLevel = math.clamp(energyLevel - ENERGY_COST, 0, 1)
	startime = tick()
	--energy.Size = UDim2.new(energyLevel, 0,  energy.Size.Y.Scale, 0)
end

UserInputService.InputBegan:Connect(onKeyPress)
-- Affichage du temps restant du boost
RunService.Heartbeat:Connect(function()
	if not startime or not humanoid then return end

	local elapsed = TIMELAPS - (tick() - startime)
	if elapsed > 0 then
		chrono.Visible = true
		chrono.Text = formatTime(elapsed)
	else
		startime = nil
		humanoid.JumpHeight = jumpHeight
		humanoid.WalkSpeed = walkSpeed
		chrono.Visible = false
		energyLevel = math.clamp(energyLevel - ENERGY_COST, 0, 1)
		energy.Size = UDim2.new(energyLevel, 0,  energy.Size.Y.Scale, 0)
	end
end)
Catégories
Jeu vidéo ROBLOX ROBLOX-NIVEAU02

Zone de boosts

Crée quatre parts avec un pouvoir pour chaque part :

  • devenir transparent
  • changer de taille
  • courir plus vite
  • sauter plus haut

Explication des 4 boosts

Invisibilité

Quand un joueur touche une des parts du dossier, le script vérifie s’il a déjà un dossier "Transparency" sur son Humanoid.
S’il ne l’a pas, il le crée et rend transparents tous les vêtements/accessoires et le corps du joueur (Transparency = 0.9).
S’il l’a déjà, le script le supprime et redonne au joueur son apparence normale (Transparency = 0).Un système de cooldown empêche de réactiver le pouvoir immédiatement après l’avoir utilisé.
C’est donc un interrupteur (toggle) : chaque contact avec la part active ou désactive l’invisibilité.

-- Script pour rendre invisible les joueurs qui touchent la part
local TRANSPARENCE_ACTIVE = 0.9
local TRANSPARENCE_INACTIVE = 0
local COOLDOWN = 1 -- secondes avant de pouvoir re-déclencher

local cooldowns = {} -- [character] = true pendant le cooldown

local function playerTransparency(character, transparency)
	for _, chose in ipairs(character:GetChildren()) do
		if chose:IsA("Accessory") then
			-- Rend transparent les BasePart/Decal de l'accessoire
			for _, descendant in ipairs(chose:GetDescendants()) do
				if descendant:IsA("BasePart") or descendant:IsA("Decal") then
					descendant.Transparency = transparency
				end
			end
		elseif chose:IsA("MeshPart") then
			-- Le MeshPart lui-même est la part à rendre transparente
			chose.Transparency = transparency
		end
	end
end

-- Boucle sur toutes les parts du folder des parts pour rendre invisible
local part = script.Parent

part.Touched:Connect(function(hit)
	local character = hit.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if not humanoid then return end
	if cooldowns[character] then return end

	cooldowns[character] = true

	local existingFolder = humanoid:FindFirstChild("Transparency")
	local transparency

	if existingFolder then
		existingFolder:Destroy()
		transparency = TRANSPARENCE_INACTIVE
	else
		local folder = Instance.new("Folder")
		folder.Name = "Transparency"
		folder.Parent = humanoid
		transparency = TRANSPARENCE_ACTIVE
	end

	playerTransparency(character, transparency)

	task.wait(COOLDOWN)
	cooldowns[character] = nil
end)

Taille

  1. Quand le joueur touche la part, le script regarde si un dossier "Scale" existe déjà sur son Humanoid.
  2. S’il n’existe pas, il sauvegarde la taille actuelle du joueur, puis l’agrandit ou le rétrécit à SCALEMAX (0.3, donc joueur miniature).
  3. S’il existe déjà, le script redonne au joueur sa taille d’origine et supprime le dossier.
  4. Les 4 dimensions (hauteur, largeur, profondeur, tête) sont modifiées en même temps pour un effet cohérent.
  5. Comme pour l’invisibilité, c’est un toggle protégé par un cooldown.
local part = script.Parent

local SCALEMAX = 0.3

local COOLDOWN = 1 -- secondes avant de pouvoir re-déclencher
local cooldowns = {} -- [character] = true pendant le cooldown

part.Touched:Connect(function(plr)
	local character = plr.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if not humanoid  then return end

	if cooldowns[character] then return end
	cooldowns[character] = true

	local existingFolder = humanoid:FindFirstChild("Scale")

	if existingFolder then
		humanoid.BodyHeightScale.Value = existingFolder.Value
		humanoid.BodyWidthScale.Value = existingFolder.Value		
		humanoid.BodyDepthScale.Value = existingFolder.Value	
		humanoid.HeadScale.Value = existingFolder.Value
		existingFolder:Destroy()
	else
		local folder = Instance.new("IntValue")
		folder.Name = "Scale"
		folder.Parent = humanoid
		folder.Value = humanoid.BodyHeightScale.Value
		humanoid.BodyHeightScale.Value = SCALEMAX
		humanoid.BodyWidthScale.Value = SCALEMAX		
		humanoid.BodyDepthScale.Value = SCALEMAX	
		humanoid.HeadScale.Value = SCALEMAX
	end

	task.wait(COOLDOWN)
	cooldowns[character] = nil

end)

Vitesse

  1. Quand le joueur touche la part, le script vérifie si un dossier "Speed" existe sur son Humanoid.
  2. S’il n’existe pas, il sauvegarde la vitesse actuelle du joueur (WalkSpeed) et la remplace par SPEEDMAX (50, donc très rapide).
  3. S’il existe déjà, le script restaure la vitesse normale du joueur et supprime le dossier.
  4. Cela permet au joueur de courir beaucoup plus vite qu’en temps normal.
  5. Le cooldown évite d’activer/désactiver le pouvoir trop rapidement en boucle.
local part = script.Parent

local SPEEDMAX = 50

local COOLDOWN = 1 -- secondes avant de pouvoir re-déclencher
local cooldowns = {} -- [character] = true pendant le cooldown

part.Touched:Connect(function(plr)
	local character = plr.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if not humanoid  then return end
	
	if cooldowns[character] then return end
	cooldowns[character] = true
	
	local existingFolder = humanoid:FindFirstChild("Speed")
	
	if existingFolder then
		humanoid.WalkSpeed = existingFolder.Value
		existingFolder:Destroy()
	else
		local folder = Instance.new("IntValue")
		folder.Name = "Speed"
		folder.Parent = humanoid
		folder.Value = humanoid.WalkSpeed
		humanoid.WalkSpeed = SPEEDMAX
	end
	
	task.wait(COOLDOWN)
	cooldowns[character] = nil
	
end)

Saut

  1. Quand le joueur touche la part, le script vérifie si un dossier "Jump" existe sur son Humanoid.
  2. S’il n’existe pas, il sauvegarde une valeur puis augmente sa hauteur de saut (JumpHeight) jusqu’à JUMPMAX (80, donc saut très haut).
  3. S’il existe déjà, le script restaure la hauteur de saut d’origine et supprime le dossier.
  4. Cela permet au joueur de sauter beaucoup plus haut que d’habitude.
  5. Le cooldown protège contre une réactivation trop rapide du pouvoir.
local part = script.Parent

local JUMPMAX = 80
local COOLDOWN = 1 -- secondes avant de pouvoir re-déclencher
local cooldowns = {} -- [character] = true pendant le cooldown

part.Touched:Connect(function(plr)
	local character = plr.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if not humanoid  then return end
	
	if cooldowns[character] then return end
	cooldowns[character] = true
	
	local existingFolder = humanoid:FindFirstChild("Jump")
	
	if existingFolder then
		humanoid.JumpHeight = existingFolder.Value
		existingFolder:Destroy()
	else
		local folder = Instance.new("IntValue")
		folder.Name = "Jump"
		folder.Parent = humanoid
		folder.Value = humanoid.JumpHeight
		humanoid.JumpHeight = JUMPMAX
	end
	
	task.wait(COOLDOWN)
	cooldowns[character] = nil
	
end)

Point commun aux 4 scripts : ils utilisent tous le même mécanisme (dossier-mémoire + toggle + cooldown).

QCM pour mieux comprendre

1. Que se passe-t-il si un joueur touche deux fois la part « invisibilité » (avec le cooldown écoulé entre les deux) ?
A. Rien la deuxième fois
B. Il devient invisible puis redevient visible
C. Il meurt
D. Il devient invincible

2. À quoi sert le dossier créé (ex: "Speed", "Scale", "Jump") dans chaque script ?
A. À décorer le personnage
B. À mémoriser la valeur d’origine avant modification
C. À compter le nombre de joueurs
D. À afficher un message

3. Pourquoi y a-t-il un COOLDOWN dans chaque script ?
A. Pour ralentir le jeu
B. Pour empêcher de réactiver le pouvoir trop vite d’affilée
C. Pour supprimer le joueur
D. Pour changer la couleur de la part

4. Quelle propriété du Humanoid est modifiée par le pouvoir « saut » ?
A. WalkSpeed
B. Health
C. JumpHeight
D. Transparency

5. Que modifient ENSEMBLE BodyHeightScale, BodyWidthScale, BodyDepthScale et HeadScale ?
A. La vitesse du joueur
B. La taille du joueur
C. La transparence du joueur
D. La couleur du joueur

6. Pourquoi le pouvoir « invisibilité » doit-il aussi modifier les Accessory (accessoires) du joueur ?
A. Pour que le chapeau/les cheveux etc. deviennent transparents aussi, sinon on verrait encore une partie du joueur
B. Pour supprimer les accessoires
C. Pour donner des points au joueur
D. Pour changer la forme des accessoires

Catégories
Jeu vidéo ROBLOX ROBLOX-NIVEAU01

Courir sinon perdre

Ce script crée un piège basé sur le temps : le joueur doit traverser une zone rapidement, sinon il meurt !

Le script utilise deux parts : part (visible, solide) et hidebox (une zone invisible qui sert à détecter le joueur, comme un capteur).

hidebox.CanCollide = false veut dire que cette zone est traversable : le joueur ne la voit pas et ne se cogne pas dessus, elle sert juste à « sentir » sa présence.

Quand le joueur entre dans la zone (Touched), le script note l’heure exacte grâce à tick() et la stocke dans le tableau lethalDuration, avec le personnage comme « étiquette ».

Quand le joueur sort de la zone (TouchEnded), le script calcule le temps passé dedans : tick() - lethalDuration[character].

Si ce temps est supérieur à DELTATIME (3 secondes), c’est que le joueur a été trop lent à traverser : sa vie est mise à 0 (humanoid.Health = 0), donc il meurt.

Si le joueur traverse en moins de 3 secondes, rien ne se passe : il a réussi l’épreuve !

En résumé : c’est un chronomètre invisible qui punit les joueurs trop lents à traverser une zone, un peu comme dans un jeu de plateforme où il faut courir avant qu’un mur ou un piège ne se referme.

QCM pour collégiens

1. À quoi sert la hidebox dans ce script ?
A. À bloquer physiquement le joueur
B. À détecter le passage du joueur sans être visible ni solide
C. À afficher un message au joueur
D. À téléporter le joueur

2. Que fait tick() dans ce script ?
A. Il compte le nombre de joueurs
B. Il donne l’heure exacte au moment où il est appelé
C. Il déclenche une explosion
D. Il redémarre le script

3. Quand se déclenche TouchEnded ?
A. Quand le joueur entre dans la zone
B. Quand le joueur sort de la zone
C. Quand le joueur meurt
D. Quand le jeu commence

4. Que se passe-t-il si le joueur reste plus de 3 secondes dans la hidebox ?
A. Il gagne des points
B. Il est téléporté au départ
C. Sa vie tombe à 0 et il meurt
D. Rien, il continue de jouer normalement

5. Pourquoi utilise-t-on character comme clé dans le tableau lethalDuration ?
A. Pour donner un nom au joueur
B. Pour retenir l’heure d’entrée de CHAQUE joueur individuellement
C. Pour compter les vies du joueur
D. Pour changer la couleur du personnage

6. Que représente la variable DELTATIME ?
A. La vitesse du joueur
B. Le temps maximum autorisé pour traverser la zone
C. Le nombre de joueurs dans la partie
D. La taille de la hidebox

local part = script.Parent
local hidebox = part:FindFirstChild("Hidebox")

local DELTATIME = 3

part.Anchored = true
part.CanCollide = true
part.CanTouch = true
hidebox.Anchored = true
hidebox.CanCollide = false
hidebox.CanTouch = true

local lethalDuration= {} -- [character] = true pendant le cooldown

hidebox.Touched:Connect(function(plr)
	local character = plr.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if not humanoid  then return end
	
	lethalDuration[character] = tick()

end)

hidebox.TouchEnded:Connect(function(plr)
	local character = plr.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if not humanoid  then return end
	if tick() - lethalDuration[character] > DELTATIME then
		humanoid.Health = 0
	end
	
end)
Catégories
Jeu vidéo ROBLOX ROBLOX-NIVEAU02

Afficher un chrono du temps de parcours

Ce système affiche un chrono qui mesure le temps mis par un joueur pour aller d’un bloc de départ à un bloc d’arrivée.

Le script serveur est placé sur les blocs (départ/arrivée) : il détecte quand le joueur les touche (Touched) et décide quand le chrono doit démarrer ou s’arrêter.

Le LocalScript, lui, tourne uniquement sur l’ordinateur du joueur : il gère l’affichage du chrono à l’écran (le TextLabel).

Le serveur ne peut pas modifier directement l’écran d’un joueur : il doit envoyer un message au client via un RemoteEvent.

Le RemoteEvent fonctionne comme une messagerie entre le serveur et le client : quand le joueur touche le bloc de départ, le serveur « fire » (envoie) l’événement StartEvent.

Le LocalScript écoute cet événement avec OnClientEvent:Connect(...) et, dès qu’il le reçoit, enregistre l’heure de départ (tick()) et active running = true.

De la même façon, quand le joueur touche le bloc d’arrivée, le serveur envoie WinEvent, et le LocalScript reçoit ce signal pour arrêter le chrono (running = false).

Pendant que running est actif, la fonction RunService.Heartbeat recalcule et affiche le temps écoulé à chaque frame (60 fois par seconde environ).

La fonction formatTime transforme le nombre de secondes brut en un affichage lisible du type 01:23 (minutes:secondes).

En résumé : le serveur décide (quand démarrer/arrêter), les RemoteEvents transmettent l’info, et le LocalScript affiche le résultat à l’écran du joueur.

Petit rappel pour bien comprendre

  • Script serveur : tourne sur l’ordinateur qui héberge la partie. Il contrôle les règles du jeu, mais ne peut pas modifier ce qui s’affiche à l’écran d’un joueur précis.
  • LocalScript : tourne uniquement sur l’ordinateur du joueur. Il gère l’affichage (interface, sons, caméra…) mais ne peut pas être utilisé pour des règles importantes du jeu (sinon un joueur pourrait tricher).
  • RemoteEvent : le « pont » entre les deux. Le serveur envoie une info avec FireClient(), et le LocalScript la reçoit avec OnClientEvent:Connect().

QCM pour bien comprendre

1. Où s’exécute un LocalScript ?
A. Sur le serveur du jeu
B. Sur l’ordinateur du joueur uniquement
C. Sur tous les ordinateurs en même temps
D. Nulle part, c’est juste un fichier texte

2. Pourquoi ne peut-on pas modifier directement le TextLabel depuis le script serveur ?
A. Parce que c’est interdit par Roblox
B. Parce que le serveur n’a pas accès à l’affichage local de chaque joueur
C. Parce que le TextLabel n’existe pas sur le serveur
D. Parce que ça coûte trop cher en mémoire

3. À quoi sert un RemoteEvent ?
A. À supprimer un joueur du jeu
B. À transmettre une information entre le serveur et un client
C. À changer la couleur d’un bloc automatiquement
D. À sauvegarder les données du joueur

4. Que fait startEvent:FireClient(player) côté serveur ?
A. Il supprime le joueur
B. Il envoie un signal au client précis pour déclencher une action
C. Il démarre le jeu pour tous les joueurs
D. Il crée un nouveau RemoteEvent

5. Que fait RunService.Heartbeat dans ce script ?
A. Il vérifie les battements de cœur du joueur
B. Il exécute du code à chaque frame, ici pour actualiser l’affichage du chrono
C. Il redémarre le serveur régulièrement
D. Il compte le nombre de joueurs connectés

6. Que se passe-t-il si running vaut false ?
A. Le chrono continue de s’incrémenter
B. Le texte du chrono arrête de se mettre à jour
C. Le joueur est téléporté au départ
D. Le RemoteEvent est détruit

Crée un part pour déterminer le départ du chrono et un part pour déterminer le stop du chrono.

Puis deux RemoteEvent pour gérer le démarrage et l’arrêt du chrono :

Puis script sur le serveur pour gérer les collisions entre le player et les parts de départ et d’arrivée :

local replicatedStorage = game:GetService("ReplicatedStorage")
local remoteEvent = replicatedStorage:WaitForChild("Coursetimecheck")

local startEvent = remoteEvent.StartEvent
local winEvent = remoteEvent.WinEvent

local start = script.Parent.StartPart
local succes = script.Parent.SuccessPart

succes.SurfaceGui.Enabled = false
succes.ParticleEmitter.Enabled = false

succes.Anchored = true
succes.CanCollide = true
succes.CanTouch = true

start.Anchored = true
start.CanCollide = false
start.CanTouch = true
start.Transparency = 1

succes.Touched:Connect(function(hit)
	local character = hit.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if not humanoid then return end
	if succes.SurfaceGui.Enabled then return end
	
	remoteEvent.WinEvent:FireClient(game.Players:GetPlayerFromCharacter(character))

	succes.SurfaceGui.Enabled = true
	succes.ParticleEmitter.Enabled = true
end)

start.Touched:Connect(function(hit)
	local character = hit.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if not humanoid then return end
	
	local player = game.Players:GetPlayerFromCharacter(character)
	if not player then return end -- sécurité si ce n'est pas un joueur (NPC par ex.)

	print("StartEvent déclenché pour " .. player.Name)

	startEvent:FireClient(player)
	
end)

Et également un localScript pour l’affichage du chrono pour le joueur :

-- Récupération des services
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local RunService = game:GetService("RunService")

-- Récupération du joueur actuel et de la PlayerGui
local player = Players.LocalPlayer
local playerGui = player:WaitForChild("PlayerGui")

-- Récupération de l'UI du chrono
local chrono = playerGui:WaitForChild("ScreenGui"):WaitForChild("Frame"):WaitForChild("ChronoLabel")

-- Récupération des RemoteEvents start et stop du chrono
local remoteEventsFolder = ReplicatedStorage:WaitForChild("Coursetimecheck")
local startEvent = remoteEventsFolder:WaitForChild("StartEvent")
local stopEvent = remoteEventsFolder:WaitForChild("WinEvent")

-- Fonction pour formater le temps en minutes:secondes
local function formatTime(t)
	local minutes = math.floor(t / 60)
	local seconds = math.floor(t % 60)
	return string.format("%02d:%02d", minutes, seconds)
end

-- Variables globales pour suivre le temps et l'état du chrono
local startTime = nil
chrono.Text = "00:00"
local running = false

-- Connexion des événements serveur au client
startEvent.OnClientEvent:Connect(function()
	startTime = tick()
	running = true
end)

stopEvent.OnClientEvent:Connect(function()
	running = false
end)

-- Mise à jour continue de l'affichage du chrono
RunService.Heartbeat:Connect(function()
	if not running or not startTime then return end
	chrono.Text = formatTime(tick() - startTime)
end)
Catégories
Jeu vidéo ROBLOX ROBLOX-NIVEAU02

Devenir petit en touchant un part

Ce script est attaché à un Part (bloc) et détecte quand un joueur le touche, via l’événement Touched.

Il vérifie que c’est bien un personnage avec un Humanoid, et bloque les déclenchements répétés grâce à un système de cooldown (table cooldowns).

Si le joueur n’a pas encore été rétréci/agrandi, le script sauvegarde sa taille actuelle dans un dossier Scale, puis applique la taille SCALEMAX (0.3) à sa hauteur, largeur, profondeur et tête.

Si le joueur a déjà été modifié (le dossier Scale existe), le script lui redonne sa taille d’origine et supprime le dossier.

Autrement dit : c’est un bloc « grandir/rétrécir » qui bascule (toggle) la taille du joueur à chaque contact, avec une seconde d’attente avant de pouvoir réutiliser le bloc.

QCM : Testez votre compréhension !

1. Que fait l’événement Touched dans ce script ?
A. Il vérifie si le joueur a cliqué sur le bloc
B. Il détecte quand quelque chose touche la Part
C. Il compte le nombre de joueurs dans le jeu
D. Il détruit le bloc

2. À quoi sert la variable COOLDOWN ?
A. À changer la couleur du bloc
B. À définir la taille maximale du joueur
C. À empêcher de réutiliser le bloc trop vite
D. À supprimer le personnage

3. Que se passe-t-il si le joueur touche le bloc une deuxième fois (après le cooldown) ?
A. Rien, ça ne marche qu’une fois
B. Le joueur reprend sa taille normale
C. Le joueur devient minuscule
D. Le jeu plante

4. À quoi sert le dossier (IntValue) nommé "Scale" ?
A. À afficher un message au joueur
B. À mémoriser la taille d’origine du joueur
C. À compter le temps de cooldown
D. À stocker le nom du joueur

5. Pourquoi utilise-t-on une table cooldowns avec le character comme clé ?
A. Pour donner un nom à chaque joueur
B. Pour savoir si CE joueur précis est en cooldown
C. Pour compter les points de chaque joueur
D. Pour changer la vitesse du joueur

local part = script.Parent

local SCALEMAX = 0.3

local COOLDOWN = 1 -- secondes avant de pouvoir re-déclencher
local cooldowns = {} -- [character] = true pendant le cooldown

part.Touched:Connect(function(plr)
	local character = plr.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if not humanoid  then return end

	if cooldowns[character] then return end
	cooldowns[character] = true

	local existingFolder = humanoid:FindFirstChild("Scale")

	if existingFolder then
		humanoid.BodyHeightScale.Value = existingFolder.Value
		humanoid.BodyWidthScale.Value = existingFolder.Value		
		humanoid.BodyDepthScale.Value = existingFolder.Value	
		humanoid.HeadScale.Value = existingFolder.Value
		existingFolder:Destroy()
	else
		local folder = Instance.new("IntValue")
		folder.Name = "Scale"
		folder.Parent = humanoid
		folder.Value = humanoid.BodyHeightScale.Value
		humanoid.BodyHeightScale.Value = SCALEMAX
		humanoid.BodyWidthScale.Value = SCALEMAX		
		humanoid.BodyDepthScale.Value = SCALEMAX	
		humanoid.HeadScale.Value = SCALEMAX
	end

	task.wait(COOLDOWN)
	cooldowns[character] = nil

end)
Catégories
Jeu vidéo ROBLOX ROBLOX-NIVEAU02

Courir plus vite ou sauter plus haut en touchant un part

Courir plus vite

Ce script surveille une part (un bloc) dans le jeu, et attend qu’un joueur la touche.

Quand un joueur la touche, le script vérifie qu’il s’agit bien d’un personnage (avec un Humanoid, la partie du jeu qui gère la santé, les déplacements, etc.).

Si c’est bien un joueur, sa vitesse de déplacement (WalkSpeed) passe à 50; il devient beaucoup plus rapide (par défaut, c’est 16).

QCM — vérifie ta compréhension

1. Que fait part.Touched:Connect(...) ?
A) Il détruit la part
B) Il détecte quand quelque chose touche la part
C) Il déplace la part
D) Il change la couleur de la part

2. Pourquoi le script vérifie if not humanoid then return end ?
A) Pour vérifier que la part existe
B) Pour arrêter le script si ce qui a touché n’est pas un personnage (par exemple un objet sans Humanoid)
C) Pour ralentir le joueur
D) Pour supprimer le Humanoid

3. Que représente Humanoid dans un personnage Roblox ?
A) Le nom du joueur
B) La couleur de la peau
C) La partie qui gère la santé, les déplacements, etc.
D) Un accessoire du personnage

4. Que se passe-t-il quand humanoid.WalkSpeed = 50 s’exécute ?
A) Le joueur devient invisible
B) Le joueur saute plus haut
C) Le joueur se déplace plus vite
D) Le joueur perd de la vie

5. Si un objet SANS Humanoid (comme une simple balle) touche la part, que se passe-t-il ?
A) Le script plante avec une erreur
B) Rien, le script s’arrête grâce au return
C) La balle devient rapide
D) Le jeu redémarre

local part = script.Parent

part.Touched:Connect(function(plr)
	local character = plr.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if not humanoid  then return end
	
	humanoid.WalkSpeed = 50
		
end)

Bascule courir plus vite / normalement

Quand un joueur touche la part, le script regarde s’il a déjà une vitesse « boostée » (mémorisée dans un petit objet nommé « Speed ») : si oui, il lui rend sa vitesse normale, sinon il sauvegarde sa vitesse actuelle et le rend très rapide (50).

Un système de « cooldown » (temps d’attente) empêche le joueur de retoucher la part plusieurs fois par seconde et de faire buguer le changement de vitesse.

Ainsi, la part fonctionne comme un interrupteur : un coup pour accélérer, un coup pour revenir à la normale, avec une petite pause obligatoire entre deux touches.

QCM — vérifie ta compréhension

1. À quoi sert la variable cooldowns ?
A) À compter combien de joueurs ont touché la part
B) À empêcher un joueur de redéclencher l’effet plusieurs fois trop vite
C) À stocker la couleur de la part
D) À sauvegarder le nom du joueur

2. Que fait l’objet IntValue nommé « Speed » ?
A) Il affiche un message au joueur
B) Il mémorise la vitesse de marche du joueur avant le boost, pour pouvoir la restaurer plus tard
C) Il détruit le personnage
D) Il change la couleur de la part

3. Que se passe-t-il si le joueur touche la part une seconde fois (sans cooldown actif) ?
A) Sa vitesse redevient normale, car le dossier « Speed » existe déjà
B) Rien ne se passe
C) Sa vitesse augmente encore plus
D) Le jeu plante

4. Pourquoi utilise-t-on task.wait(COOLDOWN) à la fin de la fonction ?
A) Pour ralentir tous les joueurs du jeu
B) Pour attendre 1 seconde avant de permettre au joueur de redéclencher l’effet
C) Pour détruire la part après 1 seconde
D) Pour attendre que le joueur meure

5. Si un joueur touche la part pendant que son cooldown est actif, que fait le script ?
A) Il double sa vitesse
B) Il arrête la fonction immédiatement avec return, sans rien changer
C) Il redémarre le cooldown
D) Il supprime le dossier « Speed »

local part = script.Parent

local SPEEDMAX = 50

local COOLDOWN = 1 -- secondes avant de pouvoir re-déclencher
local cooldowns = {} -- [character] = true pendant le cooldown

part.Touched:Connect(function(plr)
	local character = plr.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if not humanoid  then return end
	
	if cooldowns[character] then return end
	cooldowns[character] = true
	
	local existingFolder = humanoid:FindFirstChild("Speed")
	
	if existingFolder then
		humanoid.WalkSpeed = existingFolder.Value
		existingFolder:Destroy()
	else
		local folder = Instance.new("IntValue")
		folder.Name = "Speed"
		folder.Parent = humanoid
		folder.Value = humanoid.WalkSpeed
		humanoid.WalkSpeed = SPEEDMAX
	end
	
	task.wait(COOLDOWN)
	cooldowns[character] = nil
	
end)

Essaye le même système pour faire sauter plus haut :

	humanoid.JumpHeight = 20
local part = script.Parent

local SCALEMAX = 4

local COOLDOWN = 1 -- secondes avant de pouvoir re-déclencher
local cooldowns = {} -- [character] = true pendant le cooldown

part.Touched:Connect(function(plr)
	local character = plr.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if not humanoid  then return end

	if cooldowns[character] then return end
	cooldowns[character] = true

	local existingFolder = humanoid:FindFirstChild("Scale")

	if existingFolder then
		humanoid.BodyHeightScale.Value = existingFolder.Value
		humanoid.BodyWidthScale.Value = existingFolder.Value		
		humanoid.BodyDepthScale.Value = existingFolder.Value	
		humanoid.HeadScale.Value = existingFolder.Value
		existingFolder:Destroy()
	else
		local folder = Instance.new("IntValue")
		folder.Name = "Scale"
		folder.Parent = humanoid
		folder.Value = humanoid.BodyHeightScale.Value
		humanoid.BodyHeightScale.Value = SCALEMAX
		humanoid.BodyWidthScale.Value = SCALEMAX		
		humanoid.BodyDepthScale.Value = SCALEMAX	
		humanoid.HeadScale.Value = SCALEMAX
	end

	task.wait(COOLDOWN)
	cooldowns[character] = nil

end)

Traverser le plus vite possible autrement ..

Catégories
Jeu vidéo ROBLOX ROBLOX-NIVEAU02

Devenir invisible en touchant un part

Rendre transparent le player

Ce script Roblox rend transparents (invisibles à 75%) les joueurs ou leurs accessoires (comme un chapeau ou une épée) quand ils touchent une pièce (la part). Il vérifie si ce qui a touché la pièce est un personnage avec un Humanoid (un joueur).
Ensuite, il parcourt toutes les parties du personnage (corps, accessoires) et les rend transparentes.
Seules les pièces 3D (BasePart, MeshPart) ou les textures (Decal) sont modifiées.

QCM : Teste ta compréhension !

1. Que fait ce script quand un joueur touche la pièce ?
A) Il supprime le joueur.
B) Il rend le joueur et ses accessoires transparents.
C) Il change la couleur du joueur en rouge.
D) Il fait exploser la pièce.

2. Pourquoi vérifie-t-on if not humanoid then return end ?
A) Pour éviter que le script ne s’applique aux objets qui ne sont pas des joueurs.
B) Pour accélérer le jeu.
C) Pour rendre la pièce invisible.
D) Pour ajouter un accessoire au joueur.

3. Que signifie descendant.Transparency = 0.75 ?
A) La pièce devient complètement invisible.
B) La pièce devient à 75% transparente (presque invisible).
C) La pièce clignote.
D) La pièce devient plus grande.

4. Quel type d’objet n’est PAS modifié par ce script ?
A) Un chapeau (Accessory).
B) Une épée (MeshPart).
C) Un mur (Part).
D) Une texture (Decal) sur un accessoire.

-- Script pour rendre invisible les joueurs qui touchent la part
local part = script.Parent

part.Touched:Connect(function(hit)
	local character = hit.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if not humanoid  then return end

	for _, chose in ipairs(character:GetChildren()) do
		if chose:IsA("Accessory") then
			-- Rend transparent les BasePart/Decal de l'accessoire
			for _, descendant in ipairs(chose:GetDescendants()) do
				if descendant:IsA("BasePart") or descendant:IsA("Decal") then
					descendant.Transparency = 0.75
				end
			end
		elseif chose:IsA("MeshPart") then
			-- Le MeshPart lui-même est la part à rendre transparente
			chose.Transparency = 0.75
		end
	end
end)

Bascule invisible/visible

Ce script Roblox permet de rendre un joueur transparent à 50% quand il touche une pièce, puis de le rendre à nouveau visible s’il la touche une deuxième fois.
Il utilise un délai de 1 seconde (COOLDOWN) pour éviter de déclencher l’effet trop vite.
Un dossier caché (Transparency) est créé dans le personnage pour « mémoriser » s’il est déjà transparent.
Seuls les joueurs (avec un Humanoid) sont concernés, et leurs accessoires ou parties du corps deviennent transparents.

QCM : Teste ta compréhension !

1. Que fait ce script quand un joueur touche la pièce pour la première fois ?
A) Il le supprime.
B) Il le rend transparent à 50%.
C) Il le rend complètement invisible.
D) Il le fait sauter.

2. Pourquoi utilise-t-on cooldowns[character] = true ?
A) Pour empêcher le joueur de déclencher l’effet plusieurs fois en 1 seconde.
B) Pour rendre le joueur invincible.
C) Pour changer la couleur de la pièce.
D) Pour ajouter un accessoire au joueur.

3. À quoi sert le dossier Transparency dans le Humanoid ?
A) À stocker si le joueur est déjà transparent pour inverser l’effet au prochain contact.
B) À rendre le joueur plus rapide.
C) À supprimer le personnage.
D) À afficher un message.

4. Que se passe-t-il si un joueur touche la pièce une deuxième fois ?
A) Il devient à nouveau visible (transparence à 0%).
B) Il devient complètement invisible.
C) Il explose.
D) Rien, le script ne fait plus rien.

-- Script pour rendre invisible les joueurs qui touchent la part
local part = script.Parent

local TRANSPARENCE_ACTIVE = 0.5
local TRANSPARENCE_INACTIVE = 0
local COOLDOWN = 1 -- secondes avant de pouvoir re-déclencher

local cooldowns = {} -- [character] = true pendant le cooldown

local function playerTransparency(character, transparency)
	for _, chose in ipairs(character:GetChildren()) do
		if chose:IsA("Accessory") then
			-- Rend transparent les BasePart/Decal de l'accessoire
			for _, descendant in ipairs(chose:GetDescendants()) do
				if descendant:IsA("BasePart") or descendant:IsA("Decal") then
					descendant.Transparency = transparency
				end
			end
		elseif chose:IsA("MeshPart") then
			-- Le MeshPart lui-même est la part à rendre transparente
			chose.Transparency = transparency
		end
	end
end

part.Touched:Connect(function(hit)
	local character = hit.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if not humanoid then return end
	if cooldowns[character] then return end

	cooldowns[character] = true

	local existingFolder = humanoid:FindFirstChild("Transparency")
	local transparency

	if existingFolder then
		existingFolder:Destroy()
		transparency = TRANSPARENCE_INACTIVE
	else
		local folder = Instance.new("Folder")
		folder.Name = "Transparency"
		folder.Parent = humanoid
		transparency = TRANSPARENCE_ACTIVE
	end

	playerTransparency(character, transparency)

	task.wait(COOLDOWN)
	cooldowns[character] = nil
end)

Gestion d’un folder pour gérer plusieurs parts pour rendre invisible

-- Boucle sur toutes les parts du folder des parts pour rendre invisible
local folder = workspace:FindFirstChild("Zone Invisibilite", true)


for _, part in ipairs(folder:GetChildren()) do

	if not part:IsA("BasePart") then return end

	part.Touched:Connect(function(hit)
		local character = hit.Parent
		local humanoid = character and character:FindFirstChild("Humanoid")
		if not humanoid then return end
		if cooldowns[character] then return end

		cooldowns[character] = true

		local existingFolder = humanoid:FindFirstChild("Transparency")
		local transparency

		if existingFolder then
			existingFolder:Destroy()
			transparency = TRANSPARENCE_INACTIVE
		else
			local folder = Instance.new("Folder")
			folder.Name = "Transparency"
			folder.Parent = humanoid
			transparency = TRANSPARENCE_ACTIVE
		end

		playerTransparency(character, transparency)

		task.wait(COOLDOWN)
		cooldowns[character] = nil
	end)

end

Traverser un mur quand le player est transparent

Quand un personnage touche la Part, le script vérifie s’il a un Humanoid possédant un attribut/valeur nommé "Transparency" , si oui, il rend la Part traversable (CanCollide = false).

Quand ce même personnage arrête de toucher la Part (TouchEnded), le script refait la vérification et remet la Part solide (CanCollide = true).

Résultat : c’est un bloc qui devient traversable uniquement pour les joueurs possédant la valeur « Transparency » (par exemple des joueurs rendus invisibles/fantômes ailleurs dans le jeu), et redevient solide dès qu’ils sont passés.

QCM : Teste ta compréhension !

1. Que vérifie le script avant de rendre la Part traversable ?
A. Que le joueur a un pseudo spécial
B. Que le personnage possède une valeur nommée « Transparency »
C. Que le joueur est en l’air
D. Que la Part est de couleur rouge

2. Que fait part.CanCollide = false ?
A. Le bloc devient invisible
B. Le bloc disparaît définitivement
C. Le bloc laisse passer les objets/joueurs à travers
D. Le bloc explose

3. Quand se déclenche l’événement TouchEnded ?
A. Quand le joueur commence à toucher la Part
B. Quand le joueur arrête de toucher la Part
C. Quand le joueur meurt
D. Quand le jeu se termine

4. Que se passe-t-il si un joueur SANS la valeur « Transparency » touche la Part ?
A. Il traverse quand même le bloc
B. Rien ne change, la Part reste solide pour lui
C. Il devient invisible
D. La Part se détruit

5. Pourquoi remet-on CanCollide = true dans TouchEnded ?
A. Pour empêcher d’autres joueurs (sans la bonne valeur) de traverser après
B. Pour changer la couleur du bloc
C. Pour supprimer le joueur
D. Pour recommencer le jeu

local part = script.Parent

part.Touched:Connect(function(hit)
	local character = hit.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if not humanoid then return end

	local existingFolder = humanoid:FindFirstChild("Transparency")
	if not existingFolder then return end
	part.CanCollide= false

end)

part.TouchEnded:Connect(function(hit)
	local character = hit.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if not humanoid then return end
	
	local existingFolder = humanoid:FindFirstChild("Transparency")
	if not existingFolder then return end	
	part.CanCollide= true

end)
Catégories
Jeu vidéo ROBLOX ROBLOX-NIVEAU02

Téléportation d’un point A à un point B :

Voici l’explication du code, ligne par ligne :

Les variables de départ

local teleports = script.Parent
local teleportA = teleports.TeleportA
local teleportB = teleports.TeleportB

On récupère deux objets dans le jeu Roblox : la plateforme A (celle sur laquelle on va marcher) et la plateforme B (celle où on va arriver). Ces deux plateformes sont des enfants du script dans l’arbre du jeu.

L’événement Touched

teleportA.Touched:Connect(function(hit)

Touched est un événement Roblox : il se déclenche automatiquement dès que quelque chose touche la plateforme A. Le paramètre hit contient la pièce (la partie du corps) qui l’a touchée.

La vérification du joueur

local character = hit.Parent
local humanoid = character and character:FindFirstChildOfClass("Humanoid")
if not humanoid or humanoid.Health <= 0 then return end

On remonte d’un niveau pour trouver le personnage entier (hit.Parent), puis on cherche s’il contient un Humanoid (ce qui prouve que c’est bien un joueur, pas un mur ou une balle). Si rien de valide n’est trouvé, ou si le joueur est mort (Health <= 0), on arrête tout avec return.

La téléportation

local offset = Vector3.new(0, 2, 0)
character:PivotTo(CFrame.new(teleportB.Position + offset))

Vector3.new(0, 2, 0) crée un décalage de 2 unités vers le haut pour que le joueur atterrisse au-dessus de la plateforme B et pas à l’intérieur. PivotTo est la fonction qui déplace instantanément tout le personnage à une nouvelle position — c’est ça la téléportation !

Le code complet de la téléportation

-- Configuration
local teleports = script.Parent
local teleportA = teleports.TeleportA
local teleportB = teleports.TeleportB

teleportA.Touched:Connect(function(hit)
	-- Récupération du joueur
	local character = hit.Parent
	local humanoid  = character and character:FindFirstChildOfClass("Humanoid")
	if not humanoid or humanoid.Health <= 0 then return end
	
	-- Décalage légert vers le haut pour poser le joueur sur la plateforme
	local offset = Vector3.new(0, 2, 0)
	character:PivotTo(CFrame.new(teleportB.Position + offset))

end)
Catégories
Jeu vidéo ROBLOX ROBLOX-NIVEAU02

Crée un tableau de scores

Objectif : Créé un tableau de scores

Créer un script pour afficher un tableau de score au joueur sousServerScriptService :

Renommer le script leaderstats :

Saisir le code suivant pour un affichage d’une barre de scores :

local players = game:GetService("Players")

players.PlayerAdded:Connect(function(player)
     local leaderstats = Instance.new("Folder")
     leaderstats.Name = "leaderstats"
     leaderstats.Parent = player
end)

Si tu lances ton jeu une barre s’affiche :

Si le score ne s’affiche pas vérifie :

Rajoute à ton script un score à afficher :

local players = game:GetService("Players")

players.PlayerAdded:Connect(function(player)

     local leaderstats = Instance.new("Folder")
     leaderstats.Name = "leaderstats"
     leaderstats.Parent = player

     local score = Instance.new("IntValue")
     score.Parent = leaderstats
     score.Name = "Score"
     score.Value = 0

end)

Le score s’affiche si tu lances ton jeu :

Exemple d’un script pour augmenter le score si le joueur click sur un ClickDetector :

local clickDetector = script.Parent.ClickDetector

clickDetector.MouseClick:Connect(function(player)

      player:WaitForChild("leaderstats").Score.Value += 10

end)

Exemple d’un script pour augmenter le score si le joueur rentre en collision avec un part :

local myPart = script.Parent


myPart.Touched:Connect(function(hit)

	-- Vérifie si c'est un joueur qui a touché la part
	local joueur = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
	if joueur then
		-- Trouve le score du joueur dans Leaderstats
		local leaderstats = joueur:FindFirstChild("leaderstats")
		if leaderstats then
			local score = leaderstats:FindFirstChild("Score")
			if score then
				-- Incrémente le score
				score.Value = score.Value + 1
			end
		end
	end

end)

Exemple d’un script pour augmenter le score si le joueur rentre en collision avec un part :

local myPart = script.Parent


myPart.Touched:Connect(function(hit)

	-- Vérifie si c'est un joueur qui a touché la part
	local joueur = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
	if joueur then
		-- Trouve le score du joueur dans Leaderstats
		local leaderstats = joueur:FindFirstChild("leaderstats")
		if leaderstats then
			local score = leaderstats:FindFirstChild("Score")
			if score then
				-- Incrémente le score
				score.Value = score.Value + 1
			end
		end
	end

end)

Un système de score avec un ModuleScript

1. Créer un ModuleScript pour gérer les scores

-- ModuleScript dans ServerScriptService : "ScoreManager"
local ScoreManager = {}

-- Initialise le Leaderstats pour un joueur
function ScoreManager.initPlayer(player)
    local leaderstats = Instance.new("Folder", player)
    leaderstats.Name = "leaderstats"

    local points = Instance.new("IntValue", leaderstats)
    points.Name = "Score"
    points.Value = 0
end

-- Met à jour le score d'un joueur
function ScoreManager.addPoints(player, points)
    local leaderstats = player:FindFirstChild("leaderstats")
    if leaderstats then
        local score = leaderstats:FindFirstChild("Score")
        if score then
            score.Value = score.Value + points
        end
    end
end

return ScoreManager

Appel dans scriptServeur pour rajouter des points :

-- Script dans ServerScriptService
local ScoreManager = require(game:GetService("ServerScriptService"):WaitForChild("ScoreManager"))

-- Initialiser le Leaderstats pour chaque joueur
game.Players.PlayerAdded:Connect(function(player)
	ScoreManager.initPlayer(player)
end)

local part = workspace.Part -- La Part qui déclenche l'événement

-- Exemple : Ajouter 10 points à un joueur
part.Touched:Connect(function(otherPart)
	-- Vérifie que otherPart fait partie d'un personnage
	local humanoid = otherPart.Parent:FindFirstChild("Humanoid")
	if humanoid then
		-- Récupère le joueur associé au personnage
		local player = game.Players:GetPlayerFromCharacter(otherPart.Parent)
		if player then            
			ScoreManager.addPoints(player, 10)
			part:Destroy() -- Supprime la Part après utilisation

		end
	end
end)
Catégories
Jeu vidéo ROBLOX

Apprendre Lua sur Roblox – 10 scénarios simples

Voici les 10 mini-projets interactifs ! Cliquez sur les défi01 à défi10 pour naviguer entre les projets.

Chaque fiche contient :

  • la description du jeu, les règles,
  • les compétences Lua acquises,
  • un QCM de 5 questions

La progression suit une logique pédagogique :

  • défi01 à défi03 : bases Roblox (Parts, inputs, GUI)
  • défi04 à défi06 : communication réseau, physique, effets visuels
  • défi07 à défi09 : animations, interactions avancées, données persistantes
  • défi10 : projet complet qui réutilise tout, avec architecture modulaire

Défi 01 : La Zone Mortelle

Description

Une course parsemée de difficultés et de briques mortelles. Le joueur doit traverser des espaces en utilisant des pouvoirs à sa disposition (sauter plus haut, courir plus vite, rétrécir, devenir transparent pour passer à travers les murs. Au contact d’un part mortel, son personnage meurt instantanément (Humanoid.Health = 0). Des zones sûres (parts verts) permettent de souffler avant d’atteindre une zone verte de victoire.

Règles du jeu

Rejoignez l’arène verte de victoire à l’autre bout du parcours en utilisant les pouvoirs à votre disposition. Chaque mort vous remet au départ. Pas de limite de tentatives.

Voir un exemple sous ROBLOX

Compétences acquises

  • Touched Event
  • Humanoid.Health
  • BasePart properties
  • Script vs Local
  • for _ , part in ipair(parts:GetChildren())
  • Reconnaître un Humanoid
  • Gérer les collisions

QCM — Testez vos connaissances

1. Quel événement Roblox détecte le contact avec une part ?

  • OnTouch
  • Touched
  • Hit
  • Collide

2. Pour tuer un personnage, on modifie quelle propriété du Humanoid ?

  • MaxHealth
  • WalkSpeed
  • Health
  • Jump

3. Où place-t-on un Script qui affecte le serveur ?

  • StarterGui
  • ReplicatedStorage
  • ServerScriptService
  • LocalScript

4. Comment récupérer le Humanoid d’un personnage touché ?

  • hit.Humanoid
  • hit.Parent:FindFirstChild(‘Humanoid’)
  • game.Players.Humanoid
  • workspace.Humanoid

5. Quelle propriété rend une Part non-solide mais visible ?

  • Transparency = 0
  • CanCollide = false
  • Anchored = true
  • Locked = true

Défi 02 : Speed Runner

Touches clavier & compétences joueur

Description

Un parcours d’obstacles où le joueur peut débloquer une compétence en appuyant sur une touche du clavier. Appuyez sur [F] pour activer un boost d’un saut et vitesse rapide temporaire. Le boost a un cooldown visible et une barre d’énergie.

Des checkpoints invisibles qui font respawn le joueur au bon endroit si le joueur tombe ou meurt. Un compteur de tours : combien de fois le joueur a terminé le parcours. Un meilleur temps (record) qui s’affiche et se met à jour automatiquement

Règles du jeu

Parcourez le parcours le plus vite possible. Utilisez votre touche de compétence au bon moment. Franchissez la ligne d’arrivée. Votre temps est affiché.

Voir un exemple sous ROBLOX

Compétences acquises

  • UserInputService
  • ServiceHumanoid.WalkSpeed
  • Humanoid.Jump
  • Powercooldown avec tick()

QCM — Testez vos connaissances

  1. Quel service Roblox gère les entrées clavier côté client ?
  • InputServiceUser
  • InputService
  • KeyboardService
  • ContextService

2. Dans quel type de script utilise-t-on UserInputService ?

  • ScriptModule
  • ScriptLocal
  • ScriptServer
  • Script

3. Comment détecter l’appui sur la touche E ?

  • Enum.KeyCode.E
  • Key.E
  • Input.E
  • Keyboard.E

4. Quelle propriété du Humanoid contrôle la vitesse de marche ?

  • Speed
  • RunSpeed
  • WalkSpeed
  • MoveSpeed

5. tick() retourne quoi en Lua Roblox ?

  • Le tick d’horloge en ms
  • Le temps en secondes depuis le lancement
  • Le framerate actuel
  • Le temps depuis le début de la partie

Défi 03 : Le Magasin de Pouvoirs

GUI & ScreenGui

Description

Un magasin en jeu affiché via un ScreenGui. Le joueur ouvre l’interface avec [G] et voit une liste de pouvoirs à acheter (vitesse, saut, bouclier). Chaque pouvoir a un prix en pièces d’or ramassées dans le monde. L’achat est confirmé par un bouton.

Règles du jeu

Collectez des pièces d’or dans la carte. Appuyez sur [G] pour ouvrir la boutique. Achetez des pouvoirs avec vos pièces. Activez vos pouvoirs via les touches attribuées.

Compétences acquises

  • ScreenGui & Frame
  • TextButton.MouseButton1Click
  • RemoteEvent (achat)
  • leaderstats basiques
  • Visible toggle

QCM — Testez vos connaissances

  1. Où place-t-on un ScreenGui pour qu’il s’affiche à tous les joueurs ?
  • Workspace
  • StarterGui
  • ReplicatedStorage
  • ServerStorage

2. Quel événement déclenche un clic sur un TextButton ?

  • MouseButton1Click
  • Clicked
  • OnClick
  • Activated

3. Comment rendre une Frame invisible via Script ?

  • Frame.Hide()
  • Frame.Enabled = false
  • Frame.Visible = false
  • Frame.Alpha = 0

4. Un RemoteEvent sert à quoi ?

  • Communiquer entre LocalScript et Script serveur
  • Créer des GUI
  • Détecter les touches
  • Gérer les collisions

5. Pour déclencher un RemoteEvent depuis le client vers le serveur, on utilise ?

  • RemoteEvent:FireServer()
  • RemoteEvent:FireClient()
  • RemoteEvent:Send()
  • RemoteEvent:Trigger()

Défi 04 : La Porte Télékinésique

RemoteEvents & communication Client/Sserveur

Description

Des portes et pièges contrôlés en réseau. Quand un joueur marche sur un bouton (Part), un RemoteEvent notifie le serveur qui ouvre la porte correspondante pour TOUS les joueurs. Des pièges s’activent de même en temps réel.

Règles du jeu

Explorez la carte coopérativement. Trouvez les boutons cachés qui ouvrent des portes. Un joueur peut sacrifier sa position pour ouvrir le chemin à ses coéquipiers. Atteignez la sortie ensemble.

Compétences acquises

  • RemoteEvent:FireServer
  • RemoteEvent:FireClient
  • RemoteEvent.OnServerEvent
  • ReplicatedStorage
  • synchronisation multi-joueurs

QCM — Testez vos connaissances

1. Où stocke-t-on les RemoteEvents accessibles client ET serveur ?

  • ServerStorage
  • ServerScript
  • ServiceReplicated
  • StorageStarterGui

2. OnServerEvent est connecté dans quel type de script ?

  • LocalScript
  • Script (serveur)
  • ModuleScript
  • PluginScript

3. FireClient() envoie un event à ?

  • Tous les joueurs
  • Un joueur spécifique
  • Le serveur
  • Le workspace

4. FireAllClients() envoie à ?

  • Un joueur
  • Le serveur uniquement
  • Tous les clients connectés
  • Les NPC seulement

5. Quel est le premier paramètre reçu par OnServerEvent ?

  • Les données envoyées
  • Le joueur (Player) émetteur
  • Le nom du Remote
  • Eventnil

Défi 05 : Les Plateformes Mobiles

Mouvement de Parts via Script

Description

Des plateformes qui se déplacent selon des trajectoires (haut/bas, gauche/droite, circulaire). Certaines accélèrent, d’autres s’arrêtent selon des conditions (joueur dessus, timer). Utilisez RunService ou des boucles pour animer les positions.

Règles du jeu

Sautez de plateforme en plateforme pour atteindre la tour centrale. Les plateformes bougent en continu. Certaines disparaissent après 3 secondes de contact. Atteignez le sommet.

Compétences acquises

  • CFrame et Vector3
  • RunService.Heartbeat
  • while true do / wait()
  • math.sin() pour oscillation
  • Anchored vs non-Anchored

1. Quelle propriété utilise-t-on pour déplacer une Part sans physique ?

  • Position seule
  • CFrame
  • Velocity
  • MoveDirection

2. RunService.Heartbeat s’exécute à quelle fréquence ?

  • 1 fois/seconde
  • Chaque frame (~60fps)
  • 10 fois/seconde
  • À la demande

3. math.sin() est utile pour créer quel type de mouvement ?

  • Téléportation
  • Mouvement linéaire
  • Oscillation fluide
  • Rotation fixe

4. Une part Anchored peut-elle être déplacée par CFrame ?

  • Non, elle est immobile
  • Oui, le script peut changer son CFrame
  • Seulement par les joueurs
  • Seulement via TweenService

5. Vector3.new(0, 5, 0) représente quoi ?

  • Un déplacement de 5 studs vers le bas
  • Un déplacement de 5 studs vers le haut
  • Une rotation de 5 degré
  • sUne mise à l’échelle de 5

Défi 06 : L’Atelier des Effets

ParticleEmitter & effets visuels

Description

Un laboratoire où le joueur active différents effets visuels : feu, fumée, étincelles, traînées de lumière. Des zones déclenchent des effets via Touched. Le joueur peut ramasser un ‘orbe de feu’ qui attache un effet de flamme à son personnage.

Règles du jeu

Explorez le laboratoire et touchez les zones d’activation. Ramassez des orbes pour équiper des effets sur votre personnage. Certains effets boostent vos stats en plus d’être visuels.

Compétences acquises

  • ParticleEmitter
  • Fire & Smoke objects
  • Attachment points
  • Enabled toggle
  • PointLight & SpotLight

1. Où attache-t-on un ParticleEmitter dans un modèle 3D ?

  • Directement dans Workspace
  • Dans un Attachment ou une Part
  • Dans StarterGui
  • Dans ServerStorage

2. Comment activer/désactiver un ParticleEmitter ?

  • ParticleEmitter.Start()
  • ParticleEmitter.Enabled = true/false
  • ParticleEmitter.Visible = true/false
  • ParticleEmitter.Rate = 0

3. L’objet Fire de Roblox simule quoi ?

  • Un effet de lumière uniquement
  • Des flammes visuelles directement sur une Part
  • Un dégât de brûlure
  • Une explosion

4. Un PointLight émet la lumière dans quelle direction ?

  • Devant la Part
  • Dans toutes les directions
  • Vers le haut uniquement
  • Vers le bas uniquement

5. La propriété Rate d’un ParticleEmitter contrôle quoi ?

  • La taille des particules
  • La couleur
  • Le nombre de particules émises par seconde
  • La durée de vie du ParticleEmitter

Défi 07 : L’Ascenseur Magique

TweenService & animations fluides

Description

Des ascenseurs, portes coulissantes et objets animés avec TweenService. Les transitions sont fluides grâce aux EasingStyle. Un boss oscille sur place avec un Tween en boucle. Des récompenses s’animent quand ramassées (scale up/down).

Règles du jeu

Utilisez les ascenseurs pour monter les étages. Chaque étage déverrouille une porte animée. Ramassez les cristaux (avec animation) pour gagner des points. Atteignez le dernier étage.

Compétences acquises

  • TweenService:Create()
  • TweenInfoEasing
  • Style & Easing
  • DirectionTween:Play() / Pause() / Cancel()
  • Tween.Completed event

1. Quel service Roblox gère les transitions animées ?

  • AnimationService
  • TweenService
  • RunService
  • PhysicsService

2. TweenInfo.new() prend quoi comme premier paramètre ?

  • EasingStyle
  • La durée en secondes
  • L’objet à animer
  • Le nombre de répétitions

3. EasingStyle.Bounce donne quel effet ?

  • Mouvement linéaire
  • Rebond à la fin de l’animation
  • Accélération progressive
  • Pause au milieu

4. Comment déclencher quelque chose APRÈS la fin d’un Tween ?

  • Tween.OnComplete()
  • Tween.Completed:Wait()
  • wait(tween.duration)
  • TweenService.OnDone()

5. Peut-on tweener la couleur (Color3) d’une Part ?

  • Non, seulement la position
  • Oui, Color3 est une propriété tweénable
  • Seulement via ParticleEmitter
  • Seulement avec des scripts serveur

Défi 08 : Le Marchand & Le Détective

ProximityPrompt & ClickDetector

Description

Des PNJ (statues) équipés de ProximityPrompts affichent un menu de dialogue et de commerce quand on s’approche. Des objets dans le décor ont des ClickDetectors qui révèlent des indices. Un coffre s’ouvre au clic après avoir collecté tous les indices.

Règles du jeu

Approchez-vous des PNJ pour interagir. Cliquez sur les éléments suspects pour trouver les 5 indices. Apportez les indices au bon PNJ pour ouvrir le coffre au trésor.

Compétences acquises

  • ProximityPrompt.TriggeredClick
  • Detector.MouseClick
  • distance d’interaction
  • GUI contextuel
  • état de jeu (indices trouvés)

1. ProximityPrompt.Triggered est écouté depuis quel script ?

  • Uniquement LocalScript
  • Script serveur uniquement
  • Les deux sont possibles
  • ModuleScript seulement

2. Quelle propriété définit la distance d’activation d’un ProximityPrompt ?

  • RangeMax
  • ActivationDistance
  • TriggerRadius
  • ActivationDistance

3. ClickDetector.MouseClick passe quoi comme argument ?

  • La Part cliquée
  • Le Player qui a cliqué
  • Les coordonnées du clic
  • Nil

4. Comment afficher un texte personnalisé sur un ProximityPrompt ?

  • ProximityPrompt.Label
  • ProximityPrompt.Action
  • TextProximityPrompt.Text
  • ProximityPrompt.Title

5. Quelle est la différence principale entre ClickDetector et ProximityPrompt ?

  • Aucune différence
  • ClickDetector nécessite un clic, ProximityPrompt une touche en s’approchant
  • ProximityPrompt est plus ancien
  • ClickDetector fonctionne sans script

Défi 09 : Le Grand Tournoi

Leaderstats & tableau de score

Description

Un jeu de compétition avec un classement en temps réel (leaderstats). Points gagnés en touchant des zones, en éliminant des adversaires (PvP désactivable) ou en terminant des épreuves. Le score se met à jour pour tous via le tableau Roblox natif.

Règles du jeu

Accumulez des points en 5 minutes. Éliminez des adversaires (+10pts), touchez des zones (+5pts), finissez des épreuves bonus (+25pts). Le joueur avec le plus de points gagne.

Compétences acquises

  • leaderstats dans PlayerAdded
  • IntValue & StringValue
  • PlayerRemoving cleanup
  • tri et classement
  • DataStoreService (sauvegarde basique)

1. Comment créer les leaderstats d’un joueur ?

  • Directement dans Workspace
  • Folder nommé ‘leaderstats’ dans le Player
  • Dans ReplicatedStorage
  • Via un RemoteEvent

2. Quel événement se déclenche quand un joueur rejoint la partie ?

  • Players.PlayerJoined
  • Players.PlayerAdded
  • Players.New
  • PlayerPlayers.OnJoin

3. Quelle valeur utilise-t-on pour stocker un nombre entier dans leaderstats ?

  • NumberValue
  • IntValue
  • FloatValu
  • eStringValue

4. DataStoreService sert à quoi ?

  • Afficher le leaderboard
  • Persister des données entre les sessions
  • Communiquer entre scripts
  • Gérer les équipes

5. PlayerRemoving est utile pour ?

  • Accueillir le joueur
  • Sauvegarder les données avant que le joueur parte
  • Réinitialiser la map
  • Ajouter des points

Défi 10 : ROBLOX ADVENTURE COMPLETE

Jeu complet — tous les concepts

Description

Un jeu d’aventure complet qui intègre les 9 compétences précédentes : une carte avec zones mortelles (P1), des compétences débloquables (P2), une boutique GUI (P3), des events réseau (P4), des plateformes mobiles (P5), des effets visuels (P6), des animations TweenService (P7), des PNJ interactifs (P8) et un leaderboard complet (P9). Plusieurs niveaux, un boss final avec patterns d’attaque.

Règles du jeu

Traversez 3 zones distinctes (Forêt des Pièges, Tour des Pouvoirs, Donjon du Boss). Collectez des cristaux, achetez des améliorations, interagissez avec les PNJ, esquivez les obstacles animés. Battez le boss final et terminez premier au classement. Progression sauvegardée.

Compétences acquises

  • Architecture modulaire (ModuleScript)
  • Toutes les compétences P1-P9
  • Gestion d’état global
  • Équipes & rounds
  • Optimisation & bonnes pratiques

1. Un ModuleScript retourne quoi en général ?

  • Nil
  • Un tableau ou une fonction
  • Un RemoteEvent
  • Une GUI

2. Pour partager du code entre plusieurs scripts, on utilise ?

  • Copy-paste du code
  • ModuleScript + require()
  • RemoteEvent
  • Un Script dans Workspace

3. Quelle pratique évite les memory leaks avec les events ?

  • Utiliser task.wait()
  • Déconnecter les connexions avec :Disconnect()
  • Supprimer les RemoteEvents
  • Utiliser des LocalScripts uniquement

4. task.spawn() est préféré à coroutine.wrap() car ?

  • Il est plus lent
  • Il est intégré au scheduler Roblox et plus sûr
  • Il ne fonctionne qu’en serveur
  • Il bloque le thread principal

5. Dans une architecture propre, où stocke-t-on les ModuleScripts partagés ?

  • Workspace
  • StarterGui
  • ReplicatedStorage ou ServerScript
  • ServiceStarterPack

Répondez aux 5 question(s) restante(s)…