Catégories
Jeu vidéo ROBLOX

Barrières invisibles infranchissables

Crée dans ton jeu des barrières invisibles que le joueur ne peut pas franchir. Dès que le joueur touche une barrière invisible, celle-ci se matérialise et déclenche une alarme sonore. Tu peux répliquer autant de barrières invisibles et infranchissables que tu auras besoin pour ton jeu. Ces barrières permettent à ton joueur d’être guider et l’oblige à passer par certaines étapes de ton monde.

Crée dans ton workspace l’arborescence suivante dans un Folder avec un fichier son en option, un script, un part représentant un mur :

Puis saisie ce code dans ton script :

local Players = game:GetService("Players")

-- Configuration
local TRANSPARENCY_VISIBLE = 0.7
local TRANSPARENCY_HIDDEN  = 1
local FADE_DELAY           = 2

-- Récupération des objets du folder
local wallsFolder = script.Parent

-- Fonction appelée quand un joueur touche un mur
local function onWallTouched(otherPart, wall)
	-- Vérification joueur uniquement
	local character = otherPart.Parent
	if not Players:GetPlayerFromCharacter(character) then return end
	print("Collision avec le joueur")
end

-- Lecture de tous les murs du dossier
for _, wall in wallsFolder:GetChildren() do
	if not wall:IsA("Part") then continue end

	wall.Anchored     = true
	wall.Transparency = TRANSPARENCY_HIDDEN
	wall.Material     = Enum.Material.Neon
	wall.CanCollide   = true  -- mur bloquant

	wall.Touched:Connect(function(otherPart)
		onWallTouched(otherPart, wall)
	end)
end

Lance ton jeu, le mur est invisible, si ton joueur touche le mur il reste bloqué !!! Un message dans la sortie indique que le joueur est rentré en collision avec le mur :

Afin d’indiquer au joueur qu’il ne peut pas franchir le mur invisible, on va le faire apparaître et déclencher une alarme sonore.

Modifie le script :

local Players = game:GetService("Players")

-- Configuration
local TRANSPARENCY_VISIBLE = 0.7
local TRANSPARENCY_HIDDEN  = 1
local FADE_DELAY           = 2

-- Récupération des objets du folder
local wallsFolder = script.Parent

-- Chargement du fichier sonore (si présent)
local sound = wallsFolder:FindFirstChildOfClass("Sound")
if not sound then
	warn("[CoinManager] Aucun Sound trouvé dans ", coinsFolder.Name)
end

-- Fonction appelée quand un joueur touche un mur
local function onWallTouched(otherPart, wall)
	-- Vérification joueur uniquement
	local character = otherPart.Parent
	if not Players:GetPlayerFromCharacter(character) then return end
	-- Évite les appels multiples simultanés
	if wall.Transparency == TRANSPARENCY_VISIBLE then return end
	
	-- Affichage du mur en transparence
	wall.Transparency = TRANSPARENCY_VISIBLE
	-- Son d'alerte
	if sound then
		pcall(function() sound:Play() end)
	end
	task.wait(FADE_DELAY)
	wall.Transparency = TRANSPARENCY_HIDDEN
end

-- Lecture de tous les murs du dossier
for _, wall in wallsFolder:GetChildren() do
	if not wall:IsA("Part") then continue end

	wall.Anchored     = true
	wall.Transparency = TRANSPARENCY_HIDDEN
	wall.Material     = Enum.Material.Neon
	wall.CanCollide   = true  -- mur bloquant

	wall.Touched:Connect(function(otherPart)
		onWallTouched(otherPart, wall)
	end)
end

Duplique les murs invisibles infranchissables et déplace les dans ton espace de jeu :

Catégories
Jeu vidéo ROBLOX

Créer un système de gains

Crée un système de gain pour que ton joueur puisse gagner des points. Ce tuto montre comment programmer un système de gain en attrapant des pièces de valeurs différentes. Tu pourras répliquer autant de pièces que tu le souhaites dans ton monde.

Tu peux convertir cette proposition par un système de gains autre que par des pièces. A toi d’être imaginatif !!!

Crée la structure suivante « Coins » pour ton système de gain :

Crée un Model sous workspace que tu peux renommer Coins. Puis dessous ajoute un son, puis un script et également un part pour représenter ta pièce.

Puis modifie ton script pour générer ton système de gain, le script affiche la pièce et le gain potentiel. Pour l’instant le joueur ne peut pas récupérer les pièces donc son gain :

local RunService = game:GetService("RunService")
local Players    = game:GetService("Players")

-- Configuration
local ROTATION_SPEED   = 5
local MAX_GAIN         = 10
local RESPAWN_DELAY    = 10   -- secondes avant respawn
local FADE_SPEED       = 0.05 -- vitesse de disparition
local COIN_LEADERBOARD = "Coins" --leaderstats

-- Répertoire de ton système de gains sous workspace
local coinsFolder = script.Parent
-- Chargement du fichier sonore (si présent)
local sound = coinsFolder:FindFirstChildOfClass("Sound")
if not sound then
	warn("[CoinManager] Aucun Sound trouvé dans ", coinsFolder.Name)
end

-- Initialise et retourne les composants d'une pièce
-- Ajoute à tes pièces la valeur du gain et un système de particules
local function setupCoin(coin)
	coin.Anchored = true
	coin.Transparency = 0
	coin.CanTouch   = true
	coin.CanCollide   = false

	-- Hitbox box de collision autour de la pièce
	local hitbox = Instance.new("Part")
	hitbox.Name         = "Hitbox"
	hitbox.Parent       = coin
	hitbox.Position     = coin.Position
	hitbox.Size         = Vector3.new(coin.Size.X, coin.Size.Y, coin.Size.Z)
	hitbox.Transparency = 0.5
	hitbox.CanCollide   = false
	hitbox.Anchored     = true

	-- Particule effet lorsque le pièce est touchée
	local particule = Instance.new("ParticleEmitter")
	particule.Parent           = coin
	particule.EmissionDirection = Enum.NormalId.Back
	particule.Enabled          = false
	particule.Speed            = NumberRange.new(20, 60)
	particule.Rate			   = 40
	particule.ShapeInOut	   = Enum.ParticleEmitterShapeInOut.InAndOut

	-- Billboard pour afficher le gain
	local billboard = Instance.new("BillboardGui")
	billboard.Name        = "CoinLabel"
	billboard.Adornee     = coin
	billboard.Size        = UDim2.new(0, 40, 0, 20)
	billboard.StudsOffset = Vector3.new(0, coin.Size.Y/2 + 1, 0)
	billboard.AlwaysOnTop = false
	billboard.Parent      = coin

	local label = Instance.new("TextLabel")
	label.Parent               = billboard
	label.Size                 = UDim2.new(1, 0, 1, 0)
	label.BackgroundTransparency = 1
	label.Text                 = tostring(math.random(1, MAX_GAIN))
	label.TextColor3           = Color3.fromRGB(255, 255, 0)
	label.TextStrokeTransparency = 0
	label.TextScaled           = true

	return hitbox, particule, label, billboard
end


-- Connecte la logique de collecte sur une pièce
local function connectCoin(coin)

	local hitbox, particule, label, billboard = setupCoin(coin)
	local gain = tonumber(label.Text)

end

-- Rotation & disparition progressive (Heartbeat)
RunService.Heartbeat:Connect(function()
	for _, coin in coinsFolder:GetChildren() do
		if not coin:IsA("Part") then continue end

		if coin.CanTouch then
			-- Rotation active
			if coin.Transparency > 0 then
				coin.Transparency = 0
			end
			coin.CFrame *= CFrame.Angles(0, math.rad(ROTATION_SPEED), 0)
		else
			-- Disparition progressive
			coin.Transparency = math.min(coin.Transparency + FADE_SPEED, 1)		
		end
	end
end)

-- Initialisation de toutes les pièces
for _, coin in coinsFolder:GetChildren() do
	if coin:IsA("Part") then
		connectCoin(coin)
	end
end

Puis modifie ton script pour que le joueur puisse attraper les pièces :

local RunService = game:GetService("RunService")
local Players    = game:GetService("Players")

-- Configuration
local ROTATION_SPEED   = 5
local MAX_GAIN         = 10
local RESPAWN_DELAY    = 10   -- secondes avant respawn
local FADE_SPEED       = 0.05 -- vitesse de disparition
local COIN_LEADERBOARD = "Coins" --leaderstats

-- Répertoire de ton système de gains sous workspace
local coinsFolder = script.Parent
-- Chargement du fichier sonore (si présent)
local sound = coinsFolder:FindFirstChildOfClass("Sound")
if not sound then
	warn("[CoinManager] Aucun Sound trouvé dans ", coinsFolder.Name)
end

-- Initialise et retourne les composants d'une pièce
-- Ajoute à tes pièces la valeur du gain et un système de particules
local function setupCoin(coin)
	coin.Anchored = true
	coin.Transparency = 0
	coin.CanTouch   = true
	coin.CanCollide   = false

	-- Hitbox box de collision autour de la pièce
	local hitbox = Instance.new("Part")
	hitbox.Name         = "Hitbox"
	hitbox.Parent       = coin
	hitbox.Position     = coin.Position
	hitbox.Size         = Vector3.new(coin.Size.X, coin.Size.Y, coin.Size.Z)
	hitbox.Transparency = 0.5
	hitbox.CanCollide   = false
	hitbox.Anchored     = true

	-- Particule effet lorsque le pièce est touchée
	local particule = Instance.new("ParticleEmitter")
	particule.Parent           = coin
	particule.EmissionDirection = Enum.NormalId.Back
	particule.Enabled          = false
	particule.Speed            = NumberRange.new(20, 60)
	particule.Rate			   = 40
	particule.ShapeInOut	   = Enum.ParticleEmitterShapeInOut.InAndOut

	-- Billboard pour afficher le gain
	local billboard = Instance.new("BillboardGui")
	billboard.Name        = "CoinLabel"
	billboard.Adornee     = coin
	billboard.Size        = UDim2.new(0, 40, 0, 20)
	billboard.StudsOffset = Vector3.new(0, coin.Size.Y/2 + 1, 0)
	billboard.AlwaysOnTop = false
	billboard.Parent      = coin

	local label = Instance.new("TextLabel")
	label.Parent               = billboard
	label.Size                 = UDim2.new(1, 0, 1, 0)
	label.BackgroundTransparency = 1
	label.Text                 = tostring(math.random(1, MAX_GAIN))
	label.TextColor3           = Color3.fromRGB(255, 255, 0)
	label.TextStrokeTransparency = 0
	label.TextScaled           = true

	return hitbox, particule, label, billboard
end

-- Réinitialise une pièce pour le respawn
local function resetCoin(coin)
	coin.Transparency = 0
	coin.CanTouch   = true
end

-- Connecte la logique de collecte sur une pièce
local function connectCoin(coin)

	local hitbox, particule, label, billboard = setupCoin(coin)
	local gain = tonumber(label.Text)

	hitbox.Touched:Connect(function(otherPart)
		if not coin.CanTouch then return end

		local character = otherPart.Parent
		if not character then return end

		local player   = Players:GetPlayerFromCharacter(character)
		local humanoid = character:FindFirstChildOfClass("Humanoid")
		if not player or not humanoid then return end

		-- Collecte
		coin.CanTouch   = false
		particule.Enabled = true
		billboard.Enabled = false 

		-- Lecture protégée
		local soundDuration = 1 -- fallback si pas de son
		if sound then
			pcall(function() sound:Play() end)
			soundDuration = sound.TimeLength > 0 and sound.TimeLength or 1
		end

		-- Ajout des points
		local leaderstats = player:FindFirstChild("leaderstats")
		if leaderstats and leaderstats:FindFirstChild(COIN_LEADERBOARD) then
			leaderstats.Coins.Value += gain
		end

		-- Arrêt des particules à la fin du son
		task.delay(soundDuration, function()
			if not coin or not coin.Parent then return end
			particule.Enabled = false
			particule:Clear()
		end)

		-- Relance de la pièce après un délai
		if RESPAWN_DELAY > 0 then
			task.delay(RESPAWN_DELAY, function()
				-- Attente puis respawn
				if not coin or not coin.Parent then return end
				resetCoin(coin)
			end)

		end
	end)
end

-- Rotation & disparition progressive (Heartbeat)
RunService.Heartbeat:Connect(function()
	for _, coin in coinsFolder:GetChildren() do
		if not coin:IsA("Part") then continue end

		if coin.CanTouch then
			-- Rotation active
			if coin.Transparency > 0 then
				coin.Transparency = 0
			end
			coin.CFrame *= CFrame.Angles(0, math.rad(ROTATION_SPEED), 0)
		else
			-- Disparition progressive
			coin.Transparency = math.min(coin.Transparency + FADE_SPEED, 1)		
		end
	end
end)

-- Initialisation de toutes les pièces
for _, coin in coinsFolder:GetChildren() do
	if coin:IsA("Part") then
		connectCoin(coin)
	end
end

Tu peux changer ces paramètres :

local ROTATION_SPEED = 5 — Modifie la vitesse de rotation de tes pièces
local MAX_GAIN = 10 — Modifie le système de gain de 1 à 10
local RESPAWN_DELAY = 5 — Secondes avant respawn des pièces, 0 pas de respawn des pièces
local FADE_SPEED = 0.01 — vitesse de la disparition des pièces

Duplique les pièces et place les dans ton espace de jeu :

Catégories
Jeu vidéo ROBLOX

Créer un espace d’eau

Avec ce tuto tu peux créer un océan ou une espace d’eau confiné par exemple comme une piscine.

Par script, tu généreras un plan d’eau sur toute ta map comme pour un océan ou en fonction de la taille d’un part que tu disposeras sur ton jeu.

Dans un premier temps, crée un script sur le serveur qui va générer un espace d’eau soit un océan ou un espace contraint dans un part :

Crée un ModuleScript sous ServerScriptService :

Renomme le nom du moduleScript en waterGenerator :

Saisie le code suivant pour générer un espace d’eau comme un océan ou un espace d’eau contraint par un part comme une piscine :

local waterGenerator = {}

-- Valeurs par défaut
local TAILLE_DEFAUT  = 4048
local PROFONDEUR_DEFAUT = 200

-- Privée : fonction centrale de génération
local function createWater(terrain, centreX, centreY, centreZ, tailleX, tailleY, tailleZ)
	if not terrain then
		warn("[waterGenerator] Terrain manquant.")
		return
	end	
	local cframe = CFrame.new(centreX, centreY, centreZ)
	local size   = Vector3.new(tailleX, tailleY, tailleZ)
	terrain:FillBlock(cframe, size, Enum.Material.Water)
end

-- Génère une mer plate 
-- hauteur  : niveau Y de la surface
-- profondeur : épaisseur de l'eau vers le bas
-- taille   : largeur X et Z (optionnel, défaut 4048)
function waterGenerator.createSea(terrain, hauteur, profondeur, taille)
	if not hauteur or hauteur <= 0 then
		warn("[waterGenerator] Hauteur invalide ou manquante.")
		return
	end

	profondeur = profondeur or PROFONDEUR_DEFAUT
	if profondeur <= 0 then
		warn("[waterGenerator] Profondeur invalide.")
		return
	end

	taille = taille or TAILLE_DEFAUT
	local centreY = hauteur - profondeur / 2
	createWater(terrain, 0, centreY, 0, taille, profondeur, taille)
end

-- Génère de l'eau centrée sur une Part
-- La part définit position et taille (axes intentionnellement remappés X→Z, Z→Y, Y→X)
function waterGenerator.createPart(terrain, part)
	if not part then
		warn("[waterGenerator] Part manquante.")
		return
	end
	
	-- Préparation de la part : on la fait disparaître	
	part.Anchored = true
	part.CanCollide = false
	part.Transparency = 1

	createWater(
		terrain,
		part.Position.X,
		part.Position.Y,
		part.Position.Z,
		part.Size.X,  -- tailleX 
		part.Size.y,  -- tailleY 
		part.Size.Z   -- tailleZ 
	)
end

return waterGenerator

Comment créer un océan :

Dans ton workpace, crée un script :

local terrain      = workspace.Terrain

local waterGenerator = require(game.ServerScriptService.waterGenerator)

-- Génération de la mer 
waterGenerator.createSea(terrain, 5, 200)

Si tu lances ton jeu :

Comment créer une piscine :

Crée un part qui va contenir l’eau de ta piscine :

Crée un script avec le code suivant :

local terrain      = workspace.Terrain
local piscine      = script.Parent


local waterGenerator = require(game.ServerScriptService.waterGenerator)

waterGenerator.createPart(terrain, piscine)

Lance ton jeu, tu obtiens une masse d’eau contenu dans ton part :

Et avec un peu de décor, tu obtiendras une belle piscine :

Catégories
Jeu vidéo ROBLOX

Création d’une boutique

Améliore ton jeu par des dispositifs comme par exemple une boutique.


Créer une boutique

Dans beaucoup de jeux, les joueurs peuvent acheter des objets, des vêtements, des pouvoirs ou des accessoires. La boutique sert donc à donner plus d’objectifs au joueur : gagner de l’argent dans le jeu, choisir quoi acheter et améliorer son personnage. Une boutique rend aussi le jeu plus vivant et plus intéressant.

Dans Roblox Studio, on peut construire des décors, placer des objets et ajouter des menus à l’écran. Avec le langage de programmation Lua, nous apprendrons à donner des actions aux objets et à créer les règles du jeu.

La démarche pour la construction de ta boutique sera progressive :

  • D’abord, nous apprendrons à créer l’interface de la boutique : une fenêtre avec des boutons et les noms des objets à vendre.
  • Ensuite, nous programmerons l’argent du joueur avec une variable. Puis, nous coderons les achats : lorsqu’un joueur clique sur un bouton, le programme vérifie s’il a assez d’argent. Si oui, il paie et reçoit l’objet. Sinon, un message lui indique qu’il lui manque des pièces.

Ce projet te permettra de découvrir plusieurs notions importantes en programmation : les variables, les conditions, les événements, les fonctions et l’organisation d’un vrai projet numérique. À la fin, tu disposeras d’une boutique fonctionnelle dans Roblox.

Création de la boutique :

Pout ta boutique crée :

  • une fenêtre sur ta boutique avec les options à acheter
  • un bouton pour ouvrir et fermer la fenêtre de ta boutique
  • un localscript pour gérer l’ouverture de ta boutique

Création d’un écran utilisateur pour représenter la boutique, sous StaterGui demande la création d’un ScreenGui

Sous ScreenGui crée un Frame :

Déplace et agrandit le Frame pour prendre la place de ta boutique :

Modifie les propriétés, la couleur, le contour, la transparence du Frame :

Renomme les objets de ta botique :

Sous FrameStore rajoute un TextLabel pour le titre de ta boutique :

Dans le TextLabel rajoute le titre de la boutique :

Maintenant, tu vas rajouter des boutons pour chaque Item de ta boutique :

Tu dois obtenir ce résultat :

Tu peux rajouter une image pour certain élément de ta boutique :

Recherche une image dans la boîte à outil :

Récupère l’identifiant de l’image par un clic droit sur l’image :

Copie l’identifiant dans la propriété Image de ton ImageLabel :

Sous ScreenStore crée un ImageButton qui te permettra d’ouvrir ou fermer ta boutique :

Recherche dans la boîte à outil une image pour représenter ta boutique :

Par le clic droit demande à copier l’identifiant de l’image que tu colle dans la propriété Image de ton ImageButton :

Sous ScreenStore demande la création d’un LocalScript :

Renomme ton LocalScript et tu dois obtenir ce résultat :

Maintenant, tu peux modifier le script pour ouvrir ou fermer la boutique :

-- récupération du bouton pour ouvrir la boutique
local openButton = script.Parent.OpenButton
-- récupération du frame de la boutique	
local frameStore = script.Parent.FrameStore

-- on cache le frame de la boutique au lancement du jeu par defaut	
frameStore.Visible = false

-- on écoute l'événement de clic sur le bouton pour ouvrir ou fermer la boutique
openButton.MouseButton1Click:Connect(function()
	frameStore.Visible = not frameStore.Visible
end)

Crée un tableau de points

Objectif : Créé un tableau de scores de Points

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

Renommer le script leaderstats :

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

-- récupérer le service sur les joueurs
local players = game:GetService("Players")

-- écouteur d'un nouveau joueur
players.PlayerAdded:Connect(function(player)
	-- créer un dossier leaderstats
	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 :

-- récupérer le service sur les joueurs
local players = game:GetService("Players")

-- écouteur d'un nouveau joueur
players.PlayerAdded:Connect(function(player)
	-- créer un dossier leaderstats
	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	-- créer un score de Points
	local score = Instance.new("IntValue")
	score.Parent = leaderstats
	score.Name = "Points"
	score.Value = 10
end)

Le score s’affiche si tu lances ton jeu :


GAGNER DES POINTS

Créer un Part avec un ClickDetector afin que le joueur puisse gagner des points, exemple à reproduire sur tous les objets que tu souhaites dans ton jeu :

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

Sasie le code suivant- dans le script :

-- récupérer le ClickDetector du Part
local clickDetector = script.Parent.ClickDetector

-- écouter l'événement de clic du Clickdetector
clickDetector.MouseClick:Connect(function(player)
	-- ajouter 10 Points au joueur
	player:WaitForChild("leaderstats").Points.Value += 10

end)

Lance ton jeu, maintenant à chaque clic le score de points augmente de 10 :


Acheter

Sur l’écran de sa boutique, le joueur clic sur l’item de son achat. Le LocalScript de la boutique demande via une RemoteFunction la possibilité de l’achat de l’item. Un script sur le serveur vérifie le nombre de point et la disponibilité de l’item.

Mis en place de l’échange entre le Localscript de la boutique et le serveur par un RemoteFunction :

Renomme RemoteFunction par RemoteBuy :

Puis modifie le script StoreScript lié à ta boutique :

-- récupération du bouton pour ouvrir la boutique
local openButton = script.Parent.OpenButton
-- récupération du frame de la boutique	
local frameStore = script.Parent.FrameStore

-- on cache le frame de la boutique au lancement du jeu par defaut	
frameStore.Visible = false

-- on écoute l'événement de clic sur le bouton pour ouvrir ou fermer la boutique
openButton.MouseButton1Click:Connect(function()
	frameStore.Visible = not frameStore.Visible
end)

-- on récupère le bouton de la lampe dans la boutique
local lampButton = script.Parent.FrameStore.LampButton
-- on récupère le RemoteEvent pour acheter la lampe
local remoteBuy = game:GetService("ReplicatedStorage"):WaitForChild("RemoteBuy")
-- on écoute le clic sur le bouton de la lampe pour l'acheter
lampButton.MouseButton1Click:Connect(function(itemName)
	-- on envoie une requête au serveur pour acheter la lampe
	local success, message = remoteBuy:InvokeServer("lamp")
	-- on affiche le message de retour du serveur 
	print(success, message)	
end)

Puis demande à créer un Script sur le serveur sous ServerScriptService afin de valider l’achat :

Renomme ton Script en storeScript:

Ecris ce code dans le script storeScript :

-- récupérer le RemoteFunction RemoteBuy
local remoteBuy = game:GetService("ReplicatedStorage"):WaitForChild("RemoteBuy")

-- écouter l'événement de requête d'achat du joueur
remoteBuy.OnServerInvoke = function(player, value)
	-- vérifier si le joueur a assez de points pour acheter l'objet
	local points = player:WaitForChild("leaderstats").Points.Value
	
	return true, " Achat confirmé !"
end

Lance ton jeu pour vérifier le bon fonctionnement de l’achat, tu trouveras le message de l’acquittement de l’achat dans la console.

Modifie le script storeScript pour vérifier si le joueur dispose d’assez de points pour l’achat et la disponibilité du stock :

-- récupérer le RemoteFunction RemoteBuy
local remoteBuy = game:GetService("ReplicatedStorage"):WaitForChild("RemoteBuy")

local ITEMS = {
	["lamp"] = { price = 5, stock = 2 },
	["run"] = { price = 10, stock = 1 },
	["visible"] = { price = 15, stock = 1 }
}

-- écouter l'événement de requête d'achat du joueur
remoteBuy.OnServerInvoke = function(player, value)
	-- vérifier si le joueur a assez de points pour acheter l'objet
	
	local item = ITEMS[value]

	-- Vérification stock
	if not item or item.stock <= 0 then
                return false, value .. " : Item indisponible "
	end

	-- Vérification points du joueur
	local points = player:WaitForChild("leaderstats").Points.Value
	if points < item.price then
		return false, "Points insuffisants (" .. points .. "/" .. item.price .. ")"
	end

	-- Transaction confirmée
	player.leaderstats.Points.Value -= item.price
	item.stock -= 1
	return true, "Achat confirmé !"
	
end

Rajoute sur l’écran de ta boutique un message pour indiquer au joueur la confirmation de son achat ou non :

Renomme ton TextLabel en MsgLabel :

Modifie le script storeScript pour afficher le message :

-- récupération du bouton pour ouvrir la boutique
local openButton = script.Parent.OpenButton
-- récupération du frame de la boutique	
local frameStore = script.Parent.FrameStore

-- on cache le frame de la boutique au lancement du jeu par defaut	
frameStore.Visible = false

-- on écoute l'événement de clic sur le bouton pour ouvrir ou fermer la boutique
openButton.MouseButton1Click:Connect(function()
	frameStore.Visible = not frameStore.Visible
end)

-- on récupère le bouton de la lampe dans la boutique
local lampButton = script.Parent.FrameStore.LampButton
-- on récupère le RemoteEvent pour acheter la lampe
local remoteBuy = game:GetService("ReplicatedStorage"):WaitForChild("RemoteBuy")

local msg = script.Parent.FrameStore.MsgLabel

-- on écoute l'événement de clic sur le bouton de la lampe pour l'acheter
lampButton.MouseButton1Click:Connect(function(itemName)
	-- on envoie une requête au serveur pour acheter la lampe
	local success, message = remoteBuy:InvokeServer("lamp")
	-- on affiche le message de retour du serveur sur l'acran de la boutique
	msg.Text = message
end)

Lance ton jeu pour vérifier si le message s’affiche correctement après un achat :


Création d’un outil

A mettre à la main du joueur et à présenter dans la boutique

Sous Workspace créer un outil Tool :

Renommer Tool en Lamp :

Maintenant, dessine une lampe en utilisant plusieurs parts que tu assembleras :

Colorise et choisis tes matériaux pour tes parts qui composera ta lampe, puis crée un Union de tes parts et renome l’objet obtenu en Handle :

Rajoute un SpotLight à ta lampe :

Modifie les propriétés de SpotLight pour orienter correctement le faisceau lumineux de ta lampe :

Lance ton jeu, le joueur doit pouvoirt attraper la lampe et vérifie que celle-ci est correctement orientée :

Je constate que la lampe n’est pas correctement orientée, je modifie le Grip de mon Tool pour l’orienter correctement :


AFFICHER L’OUTIL DANS LA BOUTIQUE

L’objectif est de présenter la lampe dans la boutique.

Dans un premier déplace ton outil Tool lampe sous ReplicatedStorage :

Puis tu vas modifier l’écran de ta boutique.

Supprimer le ImageLabel et remplace par un ViewportFrame :

Modifie le LocalScript StoreScript de la boutique :

-- récupération du bouton pour ouvrir la boutique
local openButton = script.Parent.OpenButton
-- récupération du frame de la boutique	
local frameStore = script.Parent.FrameStore

--[[
*** Rendre le viewport 3D de la lampe visible dans la boutique	
]]
local replicatedStorage = game:GetService("ReplicatedStorage")
local lamp = replicatedStorage:WaitForChild("Lamp")
local viewport = script.Parent.FrameStore.ViewportFrame
-- Nettoyage
viewport:ClearAllChildren()
-- Clone de l'objet
local clone = lamp:Clone()
clone.Parent = viewport
-- Caméra
local camera = Instance.new("Camera")
viewport.CurrentCamera = camera
camera.Parent = viewport
local center
local size
-- Calcul de la position de la caméra (adapté à la taille de l'objet)
if clone:IsA("Model") then
	size = clone:GetExtentsSize()
	center = clone:GetPivot().Position
else
	size = clone.Size
	center = clone.Position
end
-- Position de la caméra (à adapter selon la taille de l'objet)
camera.CFrame = CFrame.new(
	center + Vector3.new(size.X, size.Y, size.Z) * 0.8,
	center
)

-- on cache le frame de la boutique au lancement du jeu par defaut	
frameStore.Visible = false

-- on écoute l'événement de clic sur le bouton pour ouvrir ou fermer la boutique
openButton.MouseButton1Click:Connect(function()
	frameStore.Visible = not frameStore.Visible
end)

-- on récupère le bouton de la lampe dans la boutique
local lampButton = script.Parent.FrameStore.LampButton
-- on récupère le RemoteEvent pour acheter la lampe
local remoteBuy = game:GetService("ReplicatedStorage"):WaitForChild("RemoteBuy")

local msg = script.Parent.FrameStore.MsgLabel

-- on écoute l'événement de clic sur le bouton de la lampe pour l'acheter
lampButton.MouseButton1Click:Connect(function(itemName)
	-- on envoie une requête au serveur pour acheter la lampe
	local success, message = remoteBuy:InvokeServer("lamp")
	-- on affiche le message de retour du serveur sur l'acran de la boutique
	msg.Text = message
end)

Orienter l’image de l’outil pour une présentation optimum au joueur :


Mettre l’outil dans l’inventaire du joueur

Lors de l’achat de la lampe, mettre celle-ci dans l’inventaire.

Afin d’optimiser notre code, éviter des erreurs de saisie, tu vas centraliser tout ce que on appelle constante. Ces constantes sont des valeurs fixes et utilisées dans plusieurs parties du code.

Sous ReplicatedStorage crée un ModuleScript pour stocker toutes tes constantes :

local Constants = {}

Constants.POWER_RUN_MORE = "Run more"
Constants.LAMP = "Torch"
Constants.VISIBILITY = "Visibility"
Constants.MAX_SPEED = 50

return Constants

Modifie le LocalScript StoreScript de la boutique pour rajouter l’appel aux constantes :

local Constants = require(game.ReplicatedStorage.Constants)

-- récupération du bouton pour ouvrir la boutique
local openButton = script.Parent.OpenButton
-- récupération du frame de la boutique	
local frameStore = script.Parent.FrameStore

--[[
*** Rendre le viewport 3D de la lampe visible dans la boutique	
]]
local replicatedStorage = game:GetService("ReplicatedStorage")
local lamp = replicatedStorage:WaitForChild("Lamp")
local viewport = script.Parent.FrameStore.ViewportFrame
-- Nettoyage
viewport:ClearAllChildren()
-- Clone de l'objet
local clone = lamp:Clone()
clone.Parent = viewport
-- Caméra
local camera = Instance.new("Camera")
viewport.CurrentCamera = camera
camera.Parent = viewport
local center
local size
-- Calcul de la position de la caméra (adapté à la taille de l'objet)
if clone:IsA("Model") then
	size = clone:GetExtentsSize()
	center = clone:GetPivot().Position
else
	size = clone.Size
	center = clone.Position
end
-- Position de la caméra (à adapter selon la taille de l'objet)
camera.CFrame = CFrame.new(
	center + Vector3.new(size.X, size.Y, size.Z) * 0.8,
	center
)

-- on cache le frame de la boutique au lancement du jeu par defaut	
frameStore.Visible = false

-- on écoute l'événement de clic sur le bouton pour ouvrir ou fermer la boutique
openButton.MouseButton1Click:Connect(function()
	frameStore.Visible = not frameStore.Visible
end)

-- on récupère le bouton de la lampe dans la boutique
local lampButton = script.Parent.FrameStore.LampButton
-- on récupère le RemoteEvent pour acheter la lampe
local remoteBuy = game:GetService("ReplicatedStorage"):WaitForChild("RemoteBuy")

local msg = script.Parent.FrameStore.MsgLabel

-- on écoute l'événement de clic sur le bouton de la lampe pour l'acheter
lampButton.MouseButton1Click:Connect(function(itemName)
	-- on envoie une requête au serveur pour acheter la lampe
	local success, message = remoteBuy:InvokeServer("lamp")
	-- on affiche le message de retour du serveur sur l'acran de la boutique
	msg.Text = message
end)

Modifie le script storeScript sous ServerScriptService pour rajouter le module des constantes :

-- récupérer le module Constants
local Constants = require(game.ReplicatedStorage.Constants)

-- récupérer le RemoteFunction RemoteBuy
local remoteBuy = game:GetService("ReplicatedStorage"):WaitForChild("RemoteBuy")

-- écouter l'événement de requête d'achat du joueur
remoteBuy.OnServerInvoke = function(player, value)
	-- vérifier si le joueur a assez de points pour acheter l'objet
	local points = player:WaitForChild("leaderstats").Points.Value
	
	return true, " Achat confirmé !"
end

Modifie le script storeScript sous ServerScriptService, pour rajouter le contrôle des points, rajouter un tableau de tous les item de la boutique :

-- récupérer le module Constants
local Constants = require(game.ReplicatedStorage.Constants)
-- récupérer le RemoteFunction RemoteBuy
local remoteBuy = game:GetService("ReplicatedStorage"):WaitForChild("RemoteBuy")

local ITEMS = {
	[Constants.LAMP] = { price = 5, power = 10 , stock = 2 },
	[Constants.POWER_RUN_MORE] = { price = 10, power = 10, stock = 2 },
	[Constants.VISIBILITY] = { price = 15, power = 10, stock = 1 }
}

-- écouter l'événement de requête d'achat du joueur
remoteBuy.OnServerInvoke = function(player, value)
	-- vérifier si le joueur a assez de points pour acheter l'objet	
	local item = ITEMS[value]
	
        -- Vérification stock
	if not item or item.stock <= 0 then
		return false, value .. " : Item indisponible "
	end

	-- Vérification points du joueur
	local points = player:WaitForChild("leaderstats").Points.Value
	if points < item.price then
		return false, "Points insuffisants (" .. points .. "/" .. item.price .. ")"
	end

	-- Vérification si le joueur possède déjà l'item
	local newitem = player.leaderstats:FindFirstChild(Constants.POWER_RUN_MORE)
	if not newitem then
		newitem = Instance.new("IntValue")
		newitem.Parent = player.leaderstats
		newitem.Name = value	
	end
	newitem.Value += item.power
	
	-- Transaction confirmée
	player.leaderstats.Points.Value -= item.price
	item.stock -= 1

	return true, "Achat confirmé !"
	
end

Modifie le script pour rajouter la lampe dans l’inventaire du joueur :

local Constants = require(game.ReplicatedStorage.Constants)

-- récupération du bouton pour ouvrir la boutique
local openButton = script.Parent.OpenButton
-- récupération du frame de la boutique	
local frameStore = script.Parent.FrameStore

--[[
*** Rendre le viewport 3D de la lampe visible dans la boutique	
]]
local replicatedStorage = game:GetService("ReplicatedStorage")
local lamp = replicatedStorage:WaitForChild("Lamp")
local viewport = script.Parent.FrameStore.ViewportFrame
-- Nettoyage
viewport:ClearAllChildren()
-- Clone de l'objet
local clone = lamp:Clone()
clone.Parent = viewport
-- Caméra
local camera = Instance.new("Camera")
viewport.CurrentCamera = camera
camera.Parent = viewport
local center
local size
-- Calcul de la position de la caméra (adapté à la taille de l'objet)
if clone:IsA("Model") then
	size = clone:GetExtentsSize()
	center = clone:GetPivot().Position
else
	size = clone.Size
	center = clone.Position
end
-- Position de la caméra (à adapter selon la taille de l'objet)
camera.CFrame = CFrame.new(
	center + Vector3.new(size.X, size.Y, size.Z) * 0.8,
	center
)

-- on cache le frame de la boutique au lancement du jeu par defaut	
frameStore.Visible = false

-- on écoute l'événement de clic sur le bouton pour ouvrir ou fermer la boutique
openButton.MouseButton1Click:Connect(function()
	frameStore.Visible = not frameStore.Visible
end)

-- on récupère le bouton de la lampe dans la boutique
local lampButton = script.Parent.FrameStore.LampButton
-- on récupère le RemoteEvent pour acheter la lampe
local remoteBuy = game:GetService("ReplicatedStorage"):WaitForChild("RemoteBuy")

local msg = script.Parent.FrameStore.MsgLabel

local player = game.Players.LocalPlayer

-- on écoute l'événement de clic sur le bouton de la lampe pour l'acheter
lampButton.MouseButton1Click:Connect(function(itemName)
	if not player then return end
	if not lamp then return end
	
	-- on envoie une requête au serveur pour acheter la lampe
	local success, message = remoteBuy:InvokeServer(Constants.LAMP)
	-- on affiche le message de retour du serveur sur l'acran de la boutique
	msg.Text = message
        -- ajouter la lampe dans l'inventaire du joueur
	if success then
		local backpack = player:WaitForChild("Backpack")
		lamp.Parent = player:WaitForChild("Backpack")		
	end
end)

Courir plus vite

Modifie le localScript ScreenStore pour générer le pouvoir courir plus vite :

local Constants = require(game.ReplicatedStorage.Constants)

-- récupération du bouton pour ouvrir la boutique
local openButton = script.Parent.OpenButton
-- récupération du frame de la boutique	
local frameStore = script.Parent.FrameStore

--[[
*** Rendre le viewport 3D de la lampe visible dans la boutique	
]]
local replicatedStorage = game:GetService("ReplicatedStorage")
local lamp = replicatedStorage:WaitForChild("Lamp")
local viewport = script.Parent.FrameStore.ViewportFrame
-- Nettoyage
viewport:ClearAllChildren()
-- Clone de l'objet
local clone = lamp:Clone()
clone.Parent = viewport
-- Caméra
local camera = Instance.new("Camera")
viewport.CurrentCamera = camera
camera.Parent = viewport
local center
local size
-- Calcul de la position de la caméra (adapté à la taille de l'objet)
if clone:IsA("Model") then
	size = clone:GetExtentsSize()
	center = clone:GetPivot().Position
else
	size = clone.Size
	center = clone.Position
end
-- Position de la caméra (à adapter selon la taille de l'objet)
camera.CFrame = CFrame.new(
	center + Vector3.new(size.X, size.Y, size.Z) * 0.8,
	center
)

-- on cache le frame de la boutique au lancement du jeu par defaut	
frameStore.Visible = false

-- on écoute l'événement de clic sur le bouton pour ouvrir ou fermer la boutique
openButton.MouseButton1Click:Connect(function()
	frameStore.Visible = not frameStore.Visible
end)

-- on récupère le bouton de la lampe dans la boutique
local lampButton = script.Parent.FrameStore.LampButton
-- on récupère le RemoteEvent pour acheter la lampe
local remoteBuy = game:GetService("ReplicatedStorage"):WaitForChild("RemoteBuy")

local msg = script.Parent.FrameStore.MsgLabel

local player = game.Players.LocalPlayer

local humanoid
local leaderstats
local walkSpeed
local MAXSPEED = Constants.MAX_SPEED or 50
local function setup(character)
	humanoid = character:WaitForChild("Humanoid")
	leaderstats = player:FindFirstChild("leaderstats")
	walkSpeed = humanoid.WalkSpeed
end

player.CharacterAdded:Connect(setup)

if player and player.Character then
	setup(player.Character)
end
-- on écoute l'événement de clic sur le bouton de la lampe pour l'acheter
lampButton.MouseButton1Click:Connect(function(itemName)
	if not player then return end
	if not lamp then return end
	
	-- on envoie une requête au serveur pour acheter la lampe
	local success, message = remoteBuy:InvokeServer(Constants.LAMP)
	-- on affiche le message de retour du serveur sur l'acran de la boutique
	msg.Text = message
        -- ajouter la lampe dans l'inventaire du joueur
	if success then
		local backpack = player:WaitForChild("Backpack")
		lamp.Parent = player:WaitForChild("Backpack")		
	end
end)

-- on récupère le bouton pour le pouvoir de courir plus vite
runButton.MouseButton1Click:Connect(function(itemName)
	if not player then return end
	if not leaderstats then return end
	-- on envoie une requête au serveur pour le pouvoir courir plus vite
	local success, message = remoteBuy:InvokeServer(Constants.POWER_RUN_MORE)
	-- on affiche le message de retour du serveur sur l'acran de la boutique
	msg.Text = message
end)

Vérifie que tu disposes bien du pouvoir de courir plus vite :


Ajouter le pouvoir de courir plus vite


Sur la boutique programmer le bouton « Courrir plus vite »

Objectif :

✔ programmer le bouton de la boutique « courir plus vite »
✔ envoyer une demande au serveur pour acheter le pouvoir
✔ recevoir une réponse succès ou pas
✔ activer un pouvoir avec le clavier par la touche R

Le principe du pouvoir :

Le joueur peut :

  • acheter un pouvoir “courir plus vite”
  • appuyer sur R pour l’activer
  • utiliser ce pouvoir un certain nombre de fois

Programme le clic sur le bouton « courir plus vite » :

Modifie le localScript StoreScript et ajoute en fin du script :

-- on récupère le bouton pour le pouvoir de courir plus vite
runButton.MouseButton1Click:Connect(function(itemName)
	if not player then return end
	if not leaderstats then return end
	-- on envoie une requête au serveur pour le pouvoir courir plus vite
	local success, message = remoteBuy:InvokeServer(Constants.POWER_RUN_MORE)
	-- on affiche le message de retour du serveur sur l'acran de la boutique
	msg.Text = message
end)

Programme pour que le joueur court plus vite sur l’appui de la touche R :

Modifie le localScript StoreScript et ajoute en fin du script :

--[[
	Traitement des touches du clavier pour activer/désactiver les pouvoirs du joueur
]]
-- Connecte l'événement du clavier
local UserInputService = game:GetService("UserInputService")
local runMore = false
-- Récupère l'évènement du clavier
UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if not player then return end
	if not humanoid then return end
	-- Vérifie si l'évènement est un clavier
	if input.KeyCode ~= Enum.KeyCode.Unknown then
		-- Ferme l'écran de la boutique
		frameStore.Visible = false
		-- Vérifie si la touche appuyée est R
		if input.KeyCode == Enum.KeyCode.R and not gameProcessed then
			if runMore then
				runMore = false
				humanoid.WalkSpeed = walkSpeed
			else
				-- Vérifie si le leaderstats existe et le pouvoir de courir plus vite
				if leaderstats and leaderstats:FindFirstChild(Constants.POWER_RUN_MORE) then
					local run = leaderstats:FindFirstChild(Constants.POWER_RUN_MORE)
					-- si le pouvoir est actif
					if run.Value > 0 then

						humanoid.WalkSpeed = MAXSPEED
						run.Value -= 1
						runMore	= true
					end
				end
			end
		end

	end

end)

A chaque utilisation de la touche R pour courir plus vite, le pouvoir diminue :


Fermeture automatique de la boutique

Fermer automatiquement la boutique en cliquant en dehors de la fen,être de la boutique ou en utilisant une touche du clavier.

Crée un TextButton dans un Frame qui couvre tout l’écran :

Renomme le TextButton en Background.

Donne une priorité à la fenêtre de la boutique et aux boutons de la boutique :

Modifie le localScript StoreScript :

-- on récupère le background de l'interface de la boutique
local background = script.Parent.FrameBackground.Background
--[[
	Affichage ou non de la boutique sur l'appui de l'icone de la boutique 
]]
-- on cache le frame de la boutique au lancement du jeu par defaut	
frameStore.Visible = false
background.Interactable = false

-- on écoute l'événement de clic sur le bouton pour ouvrir ou fermer la boutique
openButton.MouseButton1Click:Connect(function()
	frameStore.Visible = not frameStore.Visible
	background.Interactable = frameStore.Visible
	frameStore.MsgLabel.Text = "Choisis ton option"
end)

background.MouseButton1Click:Connect(function()
	frameStore.Visible = false
	-- rendre non cliquable
	background.Interactable = frameStore.Visible
end)

et lors de l’appui d’une touche :

--[[
	Traitement des touches du clavier pour activer/désactiver les pouvoirs du joueur
]]
-- Connecte l'événement du clavier
local UserInputService = game:GetService("UserInputService")
local runMore = false
-- Récupère l'évènement du clavier
UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if not player then return end
	if not humanoid then return end
	-- Vérifie si l'évènement est un clavier
	if input.KeyCode ~= Enum.KeyCode.Unknown then
		-- Ferme l'écran de la boutique
		frameStore.Visible = false
		background.Interactable = frameStore.Visible	
		-- Vérifie si la touche appuyée est R
		if input.KeyCode == Enum.KeyCode.R and not gameProcessed then
			if runMore then
				runMore = false
				humanoid.WalkSpeed = walkSpeed
			else
				-- Vérifie si le leaderstats existe et le pouvoir de courir plus vite
				if leaderstats and leaderstats:FindFirstChild(Constants.POWER_RUN_MORE) then
					local run = leaderstats:FindFirstChild(Constants.POWER_RUN_MORE)
					-- si le pouvoir est actif
					if run.Value > 0 then

						humanoid.WalkSpeed = MAXSPEED
						run.Value -= 1
						runMore	= true
					end
				end
			end
		end

	end

end)
Catégories
Jeu vidéo ROBLOX

Découverte mon premier jeu ROBLOX

Plusieurs exemples de scripts LUA pour changer la couleur d’un part, mourir à petit feu, devenir tout petit, glisser, voler, se téléporter, grandir, sauter plus, courir plus, crée un menu, crée une arme fatale.

Crée un Folder à ton nom pour mettre toutes tes créations :


Changer la couleur d’un part

local part = script.Parent

part.Touched:Connect(function(hit)
	part.BrickColor = BrickColor.random()
	part.Material = Enum.Material.Neon	
end)

Un part mortel :

local part = script.Parent
part.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
	humanoid:TakeDamage(10)
end)

Rendre tout petit le joueur :

local part = script.Parent

part.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

	humanoid.BodyHeightScale.Value = 0.4
	humanoid.BodyWidthScale.Value = 0.4
	humanoid.BodyDepthScale.Value = 0.4
	humanoid.HeadScale.Value = 0.4

end)

Faire glisser un part avec un clickDetector :

local part = script.Parent

local clickDetector = part.ClickDetector

clickDetector.MouseClick:Connect(function(player)
	part.Anchored = false
	part.AssemblyLinearVelocity = Vector3.new(0, 0, 50)
end)

Part pour voler avec un clickDetector :

local AntiGravity = require(game.ReplicatedStorage.AntiGravity)
local part = script.Parent 

local clickDetector = part.ClickDetector
clickDetector.MouseClick:Connect(function(player)
	part.Anchored = false
	AntiGravity.Start(part)
	part.AssemblyLinearVelocity = Vector3.new(0, 10, 10) 
end)

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)

Grandir, Sauter, Courir plus vite :

local UserInputService = game:GetService("UserInputService")

local Players = game:GetService("Players")
local player = Players.LocalPlayer
local humanoid = player.Character and player.Character:FindFirstChildOfClass("Humanoid")

local function onKeyPress(input, gameProcessed)
	if not humanoid then return end

	if input.KeyCode == Enum.KeyCode.F and not gameProcessed then
		humanoid.JumpHeight += 8
	end

	if input.KeyCode == Enum.KeyCode.G and not gameProcessed then
		humanoid.JumpHeight -= 8
	end

	print(input.KeyCode)
	if input.KeyCode == Enum.KeyCode.X and not gameProcessed then
		humanoid.WalkSpeed += 10
	end

	if input.KeyCode == Enum.KeyCode.Z and not gameProcessed then
		humanoid.WalkSpeed -= 10
	end

end

-- Connecter la fonction à l'événement InputBegan
UserInputService.InputBegan:Connect(onKeyPress)print("Hello world!")

Touches du clavier :

  • F sauter plus haut
  • G sauter moins haut
  • X courir plus vite
  • W courir moins vite
  • A grandir
  • E plus petit

Menu disponible pour le joueur :

local screenGui = script.Parent
local open = screenGui.OpenButton
local screen = screenGui.Screen
local close = screen.CloseButton
local scaleUpPlayer = screen.ScaleUpPlayerButton
local scaleDownPlayer = screen.ScaleDownPlayerButton
local runSlowerPlayer = screen.RunSlowerPlayerButton
local runFasterPlayer = screen.RunFasterPlayerButton
local jumpUpPlayer = screen.JumpUpPlayerButton
local jumpDownPlayer = screen.JumpDownPlayerButton

local replicatedStorage = game:GetService("ReplicatedStorage")
local runScalePlayer = replicatedStorage:WaitForChild("RunScalePlayer")

local runScalePlayer = replicatedStorage:WaitForChild("RunScalePlayer")
local HumanoidFinder = require(replicatedStorage.HumanoidFinder)
local StarterPlayer = game:GetService("StarterPlayer")

local humanoid, character = HumanoidFinder.GetLocal()

screen.Visible = false

open.MouseButton1Click:Connect(function()
	screen.Visible = not screen.Visible
	open.Visible = not open.Visible
end)

close.MouseButton1Click:Connect(function()
	screen.Visible = not screen.Visible
	open.Visible = not open.Visible	
end)

scaleUpPlayer.MouseButton1Click:Connect(function()
	runScalePlayer:FireServer(0.5)
end)

scaleDownPlayer.MouseButton1Click:Connect(function()
	runScalePlayer:FireServer(-0.5)
end)
		
runSlowerPlayer.MouseButton1Click:Connect(function()
	humanoid.WalkSpeed -= 10
end)

runFasterPlayer.MouseButton1Click:Connect(function()
	humanoid.WalkSpeed += 10
end)

jumpUpPlayer.MouseButton1Click:Connect(function()
	humanoid.JumpHeight += 8
end)

jumpDownPlayer.MouseButton1Click:Connect(function()
	humanoid.JumpHeight -= 8
end)

Créer une arme fatale :

Créer un objet Tool puis un part renommer Handle :

Pour réduire à l’impuissance vos adversaires :

local part = script.Parent

part.Touched:Connect(function(hit)
	if not hit then return end 
	-- 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

	humanoid:TakeDamage(10)

end)
Catégories
Jeu vidéo ROBLOX

Comment activer le mode collaboration sur un projet Roblox

Comment collaborer à plusieurs sur un même projet Roblox Studio

Travailler en équipe dans Roblox Studio permet à l’équipe de créer ensemble un même jeu, en temps réel.
Vous apprendrez à vous organiser, à dialoguer, et à partager des responsabilités comme dans un vrai studio de jeux vidéo !

Pourquoi collaborer ?

Les avantages :

  • L’équipe travaille sur le même projet, en temps réel.
  • Chaque membre de l’équipe peut utiliser ses points forts : script, construction…
  • Tous les membres partagent ses idées et se complètent : l’équipe produit un jeu plus riche et mieux pensé.
  • Vous apprenez à communiquer comme de vrais développeurs.

Les risques si on ne s’organise pas :

  • Modifier un objet qu’un autre membre est en train de changer peut générer des conflits.
  • Effacer par erreur le travail d’un autre membre.
  • Oublier d’enregistrer ou écraser la version des autres.

Règles importantes pour bien travailler en équipe :

  1. Communiquer avant de modifier un élément du jeu.
  2. Ne jamais supprimer un objet sans prévenir.
  3. Toujours sauvegarder régulièrement.
  4. Respecter les rôles définis dans l’équipe (scripteur, designer…).

ATTENTION Un seul membre de l’équipe doit créer le jeu de base

Les deux grandes étapes

Étape 1 — Un membre crée le jeu et ajoute les collaborateurs de l’équipe

Dans chaque équipe, un seul membre crée le projet Roblox Studio.

Ouvre Roblox Studio

Se connecter avec un compte 123codage inscrit sur l’ordinateur :
123codageXX (XX entre 01 et 10 selon le numéro du PC).

Crée un nouveau projet

Choisir Baseplate pour commencer.

Active la collaboration

Dans le menu du haut : Fenêtre → Collaboration → Création en équipe

Un bouton “Sauvegarder sur Roblox” apparaît → clique dessus.

Donne un nom et une description au projet

Vous devez décider en groupe :

  • le nom du jeu,
  • une courte description (quel est le but du jeu ?).

Puis clique sur Sauvegarder.

Roblox studio se relance.

Ajoute les collaborateurs

Toujours dans :
Fenêtre → Collaboration → Gérer les collaborateurs

  • Dans la zone de recherche, taper 123codage.
  • Sélectionner les comptes des membres de l’équipe (par exemple : 123codage01, 123codage05, etc.).
    → Le numéro du PC est marqué sur la tour.

Pour chaque membre :

  • Modifier ses droits
  • Choisir Modifier (autorise à tester et modifier le jeu)

La première étape est terminée !
Tu viens de créer un projet partagé et tu as ajouté les membres de l’équipe.

Étape 2 — Les autres membres ouvrent le projet partagé

Chaque membre de l’équipe doit maintenant accéder au projet :

➤1. Ouvre le site Roblox Hub

Dans un navigateur Hub Création Roblox :
https://create.roblox.com/

Vérifie que tu es connecté avec

Le login doit être 123codageXX (ton numéro de PC).

Ouvre les créations

Clique sur Créations dans le menu à gauche.

Va dans “Partagé avec moi”

Tu devrais voir le projet créé par le membre de ton équipe.

Ouvre le projet dans Studio

  • Cliquer sur le jeu
  • Choisir Modifier dans Studio

Vérifie que la collaboration est active

Lorsque Roblox Studio s’ouvre :
Dans “Création en équipe”, tu dois voir tous les membres connectés.

Vous pouvez maintenant collaborer en temps réel !

Vous êtes prêts à travailler comme de vrais développeurs Roblox !

En respectant une bonne organisation et en communiquant régulièrement, vous pourrez créer ensemble un jeu original, complet et cohérent.

Catégories
Jeu vidéo ROBLOX

ROBLOX Faire bouger des objets

Comment utiliser LinearVelocity, VectorForce et AssemblyLinearVelocity pour lancer ou faire bouger des objets.
Comment utiliser HingeConstraint pour faire ouvrir une barrière.
Comment construire une voiture et la piloter


PARTIE 01 : Lancer des balles

LinearVelocity, VectorForce et AssemblyLinearVelocity — servent tous à faire bouger des objets dans Roblox,
mais ils ne fonctionnent pas du tout de la même manière.

LinearVelocity

Ce que ça fait :
➡️ Fait bouger un objet à une vitesse constante dans une direction.
➡️ Roblox s’occupe automatiquement de calculer la force nécessaire pour maintenir cette vitesse.

C’est parfait pour :

  • Faire voler ou propulser un objet
  • Tirer des projectiles
  • Donner un mouvement stable et constant

VectorForce

Ce que ça fait :
➡️ Applique une force brute (comme une poussée de moteur ou la gravité).
➡️ La vitesse dépend de la masse de l’objet et des forces qui s’opposent.

L’objet est poussé mais ralentit ou accélère selon sa masse, sa friction, etc.

C’est parfait pour :

  • Simuler une propulsion physique réaliste
  • Faire un jetpack, un vent, une poussée de moteur
  • Ajouter une force continue (comme la gravité personnalisée)

AssemblyLinearVelocity

Ce que ça fait :
➡️ Change directement la vitesse actuelle du corps rigide complet.
➡️ C’est comme “modifier” la vitesse sans appliquer de vraie force.

L’objet prend instantanément cette vitesse.
Pas de physique calculée, pas de force — juste une vitesse imposée.

📍 C’est parfait pour :

  • Faire bouger instantanément un objet
  • Lancer un objet d’un coup
  • Remettre à zéro sa vitesse facilement

Crée une balle à lancer

Crée une balle à partir de l’onglet Modèle puis Pièce et Sphère :

Renomme le part en « Balle » :

Change les propriétés suivantes du part Balle :

Déplace le part Balle sous ServerStorage :

ServerStorage permet de stocker des objets secrets ou internes au serveur (comme des scripts, modèles ou outils que les joueurs ne doivent pas voir directement). Donc la conséquence immédiate du déplacement de la balle : celle-ci n’est plus visible dans ton jeu, ni dans ton workspace.

Programme un lancer avec linearVelocity :

VectorVelocity fait bouger ta balle à une vitesse constante dans la direction du regard du joueur.

La balle rouge bouge sans la contrainte de la physique du jeu, notamment de la gravité.

Crée un script sous ServerScriptService et lance les balles devant le joueur :

-- je récupère la balle dans le ServerStorage
local ss = game:GetService("ServerStorage")
local balle= ss:WaitForChild("Balle")

-- je récupère la liste des jueurs
local players = game:GetService("Players")

-- je lance la blle avec linearVelocity
local function linearVelocityBall(player)
	
	-- je récupère le corps du joueur
	local char = player.Character or
                     player.CharacterAdded:Wait()
	local hrp = char:WaitForChild("HumanoidRootPart")

	-- Je génère une copie de la balle dans le workspace
	local ball = balle:Clone()
	ball.BrickColor = BrickColor.Red()
	ball.Parent = workspace
	ball.CFrame = hrp.CFrame * CFrame.new(0, 2, -2)

	-- J'applique à la balle une force constante 
	local lv = Instance.new("LinearVelocity")
	lv.MaxForce = math.huge
	lv.VelocityConstraintMode = 
                        Enum.VelocityConstraintMode.Vector
	lv.VectorVelocity = hrp.CFrame.LookVector * 5
	lv.Parent = ball
	
	-- J'attache cette force à la balle
	local attchment = Instance.new("Attachment")
	attchment.Parent = ball
	lv.Attachment0 = attchment
	
	-- Je détruis la balle au bout de 5 secondes
	game.Debris:AddItem(ball, 5)
end

-- Le joueur se connecte
players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function()
		for i = 1, 5 do
			task.wait(1)
			linearVelocityBall(player)		
		end
	end)
end)

VectorVelocity fait bouger ta balle à une vitesse constante dans la direction du regard du joueur.

L’objet bouge sans que tu aies besoin de gérer la physique.

Ton script instancie un Attachment. Un Attachment est un point de repère invisible dans une pièce (Part, MeshPart, etc.)
C’est comme une punaise virtuelle que tu peux placer n’importe où dans la pièce.

🔹 Il sert à :

  • indiquer un point précis où appliquer une force, un effet, ou une jointure,
  • ou relier deux objets ensemble (LinearVelocity, VectorForce).

L’objet bouge sans que tu aies besoin de gérer la physique.

Programme un lancer avec vectorForce:

Applique une force brute (comme une poussée de moteur ).
La vitesse dépend de la masse de l’objet et des forces qui s’opposent. La belle bleue est poussée mais ralentit ou accélère selon sa masse, sa friction et subit la gravité.

Modifie ton script pour le lancer avec une balle bleue :

local function vectorForceBall(player)
	
	-- je récupère le corps du joueur
	local char = player.Character or
                     player.CharacterAdded:Wait()
	local hrp = char:WaitForChild("HumanoidRootPart")

	-- Je génère une copie de la balle dans le workspace
	local ball = balle:Clone()
	ball.BrickColor = BrickColor.Blue()
	ball.Parent = workspace
	ball.CFrame = hrp.CFrame * CFrame.new(0, 2, -2)
	
	-- J'applique à la balle un VectorForce
	local vf = Instance.new("VectorForce")
	vf.RelativeTo = Enum.ActuatorRelativeTo.World
	vf.ApplyAtCenterOfMass = true
	vf.Force = hrp.CFrame.LookVector * ball:GetMass() * 5

	vf.Parent = ball

	-- J'attache cette force à la balle
	local attchment = Instance.new("Attachment")
	attchment.Parent = ball
	vf.Attachment0 = attchment
	
	-- Je détruis la balle au bout de 5 secondes
	game.Debris:AddItem(ball, 5)
end

players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function()
		for i = 1, 5 do
			task.wait(1)
			linearVelocityBall(player)
			task.wait(1)
			vectorForceBall(player)		
		end
	end)
end)

Programme un lancer avec AssemblyLinearVelocity

La balle verte prend instantanément la vitesse appliquée.
Pas de physique calculée, pas de force — juste une vitesse imposée

Modifie ton script :

local function assemblyLinearVelocityBall(player)
	
	-- je récupère le corps du joueur
	local char = player.Character or 
                     player.CharacterAdded:Wait()
	local hrp = char:WaitForChild("HumanoidRootPart")

	-- Je génère une copie de la balle dans le workspace
	local ball = balle:Clone()
	ball.BrickColor = BrickColor.Green()
	ball.Parent = workspace
	ball.CFrame = hrp.CFrame * CFrame.new(0, 2, -2)
	
        -- J'applique une vitesse à l'objet
	ball.AssemblyLinearVelocity = hrp.CFrame.LookVector *
                                      ball:GetMass() * 5
	
	-- Je détruis la balle au bout de 5 secondes
	game.Debris:AddItem(ball, 5)

end

players.PlayerAdded:Connect(function(player)
	player.CharacterAdded:Connect(function()
		task.wait(5)
		for i = 1, 5 do
			task.wait(1)
			linearVelocityBall(player)
			task.wait(1)
			vectorForceBall(player)
			task.wait(1)
			assemblyLinearVelocityBall(player)			
		end
	end)
end)

PARTIE 02 : Une barrière

Avant de commencer à construire ta barrière, choisis ces options pour ton projet :

Construction d’une barrière

Puis commence à construire ta barrière en créant un bloc :

Renomme le part en Socle :

Modifie les propriétés suivantes :

Puis un deuxième part pour la barrière :

Renomme le part en Barriere :

Avec les propriétés suivantes :

Sous ton workspace crée un Model que tu renommes en Barriere puis range les deux parts précédent sous ce Model :

Installe une charnière pour le mécanisme d’ouverture de la porte :

Avec un premier point d’appui sur la barrière et un deuxième sur le socle :

Tu dois obtenir ce résultat dans explorer :

  • deux points d’attachement un sur le socle et un autre sur la barrière,
  • une charnière HingeConstraint sur la barrière.

Tu peux régler plus précisément le point d’attachement, en sélectionnant celui-ci dans explorer et en utilisant l’outil déplacer :

Modifie les propriétés du HingeConstraint :

Si tu lances ton jeu, tu obtiens ce résultat :

Si tu changes la propriété TargetAngle :

En lançant ton jeu, tu obtiens le résultat suivant :

Automatisation d’ouverture de la barrière

Rajoute une boîte de collision transparente autour de la barrière afin d’automatiser son ouverture :

N’oublie pas d’enlever le CanCollide de la boîte de collision.

Puis crée un script dans ton Model Barriere :

Puis saisie ce script pour ouvrir et fermer automatiquement ta barrière :

-- Récupération de la barrière
local barriere = script.Parent.Barriere
-- Récupération de la boîte de collision
local boiteCollision = script.Parent.BoiteCollision

-- Quand la boîte de collision touche un un personnage
boiteCollision.Touched:Connect(function(hit)
	-- On récupère le modèle parent de la pièce touchée
	local character = hit.Parent
	-- On vérifie si ce modèle a un "Humanoid" (seuls les personnages en ont un)
	local humanoid = character:FindFirstChild("Humanoid")

	if humanoid then
		-- Ouverture de la barrière
		barriere.HingeConstraint.TargetAngle = 90
	end
end)

-- Quand la boîte de collision ne touche plus de personnage
boiteCollision.TouchEnded:Connect(function(hit)
	-- On récupère le modèle parent de la pièce touchée
	local character = hit.Parent
	-- On vérifie si ce modèle a un "Humanoid" (seuls les personnages en ont un)
	local humanoid = character:FindFirstChild("Humanoid")

	if humanoid then
		-- Fermeture de la barrière
		barriere.HingeConstraint.TargetAngle = 0
	end
end)

-- Fermeture de la barrière au début
barriere.HingeConstraint.TargetAngle = 0

Lance ton jeu pour tester ta barrière automatique :

PARTIE 03 : ROULER EN VOITURE

Choisis ces paramètres pour la construction de ton véhicule :

  • Joindre les surfaces
  • 1 pour l’incrémentation pour dimensionner les objets

Choix d’un Bloc pour le châssis de la voiture

Redimensionne le châssis de ta voiture et renomme le part en « Chassis« :

Crée un nouveau bloc pour créer les moyeux des roues de la voiture :

Choisis sa demension :

Duplique en quatre blocs :

Colle les blocs sur le châssis :

Sur les quatre côtés du châssis :

Duplique deux nouveaux blocs pour la direction, modifie la couleur :

Décoche la propriété CanCollide pour ces blocs :

Sous worksapace crée cette structure et range tous les parts de ta voiture :

Par le clic droit de la souris, demande le menu suivant :

Insére l’objet VehicleSeat :

Installe cet objet sur le châssis, cet objet représente le siège du conducteur :

Déplace cet objet sous l’arborescence de ta voiture :

Lance le jeu pour venir t’assoir sur le siège de ton véhicule :

Insère des contraintes entre les pièces de ton véhicule pour transmettre la direction :

Vision de la transmission de direction à droite

Vision de la transmission de direction à gauche

Tu dois obtenir ce résultat dans ton explorer :

Sélectionne les HingeConstraint de tes deux roues de l’avant pour modifier les propriétés suivantes :

Rappel : c’est quoi un HingeConstraint ?

Un HingeConstraint = une charnière virtuelle.
Il permet à un objet de tourner autour d’un axe (comme une porte, une roue, ou un bras robotique).

Mais quand on ajoute un moteur dessus, il peut :

  • tourner jusqu’à un certain angleServo

Quand ActuatorType = Servo

Le Servo agit comme un moteur intelligent :
il regarde la position actuelle de la pièce, puis la fait tourner jusqu’à atteindre l’angle qu’on lui demande.

👉 On lui donne une cible (TargetAngle), et il s’arrête tout seul quand il y arrive.

🔩 3️⃣ Les propriétés importantes

PropriétéRôle
TargetAnglel’angle à atteindre (en degrés)
ServoMaxTorquela force que le moteur peut exercer pour y arriver
AngularSpeedvitesse à laquelle il tourne pour atteindre l’angle
ActuatorTypedoit être mis sur Enum.ActuatorType.Servo

Tu dois obtenir la visualisation du mécanisme de la direction de tes deux roues :

Renomme les parts des roues avant droite et gauche ayant un HingeConstraint en « Direction » :

Rend invisible les deux parts des deux roues avant :

Rajoute un script sous le modèle de ta voiture :

local seat = script.Parent.VehicleSeat

local roueAvantGauche = script.Parent.RoueAvantGauche
local roueAvantDroite = script.Parent.RoueAvantDroite

local steerAngle = 30

seat:GetPropertyChangedSignal("Steer"):Connect(function()
	print("Steer =", seat.Steer)
	roueAvantGauche.Direction.HingeConstraint.TargetAngle = 
                        steerAngle * seat.Steer
	roueAvantDroite.Direction.HingeConstraint.TargetAngle = 
                        steerAngle * seat.Steer
end)

Ce script fait tourner les roues avant d’une voiture quand le joueur tourne à gauche ou à droite avec le clavier (A / D ou Q / D selon ton clavier).

📘 Le code

local seat = script.Parent.VehicleSeat

➡️ On récupère le siège de conduite de la voiture (VehicleSeat).
C’est lui qui détecte quand le joueur tourne à gauche ou à droite.

local roueAvantGauche = script.Parent.RoueAvantGauche
local roueAvantDroite = script.Parent.RoueAvantDroite

➡️ On récupère les deux roues avant du véhicule, pour pouvoir les faire pivoter.

  • RoueAvantGauche = la roue de gauche
  • RoueAvantDroite = la roue de droite

Ces roues ont chacune une charnière (HingeConstraint) qui permet de les faire tourner.

local steerAngle = 30

➡️ C’est l’angle maximum de rotation des roues (en degrés).
Ici : les roues peuvent tourner jusqu’à 30° vers la gauche ou la droite.

🧠 Maintenant, la partie importante :

seat:GetPropertyChangedSignal("Steer"):Connect(function()
	print("Steer =", seat.Steer)
	roueAvantGauche.Direction.HingeConstraint.TargetAngle = steerAngle * seat.Steer
	roueavantDroite.Direction.HingeConstraint.TargetAngle = steerAngle * seat.Steer
end)

1️⃣ seat:GetPropertyChangedSignal("Steer")

➡️ écoute la propriété Steer du siège (objet noir que l’on a inséré au dessus du véhicule).
Cette valeur change quand le joueur appuie sur :

  • Q → tourner à gauche
  • D → tourner à droite
  • Relâcher les touches → revenir droit

2️⃣ seat.Steer

Cette valeur peut être :

  • -1 → le joueur tourne à gauche
  • 0tout droit
  • 1 → le joueur tourne à droite

3️⃣ steerAngle * seat.Steer

➡️ C’est un calcul pour savoir de combien tourner les roues :

SteerCalculRésultat
130 × 1roues tournées à +30° (droite)
030 × 0roues droites
-130 × -1roues tournées à -30° (gauche)

4️⃣ Application de l’angle

roueAvantGauche.Direction.HingeConstraint.TargetAngle = steerAngle * seat.Steer
roueAvantDroite.Direction.HingeConstraint.TargetAngle = steerAngle * seat.Steer

➡️ Le script change l’angle cible (TargetAngle) de la charnière des roues avant.
👉 Résultat : quand le joueur tourne, les roues s’inclinent à gauche ou à droite comme une vraie voiture 🚘

🧠 En résumé

ÉlémentRôle
VehicleSeatdétecte les touches du joueur
Steerindique la direction du volant (-1, 0, 1)
HingeConstraintpermet de faire tourner les roues
TargetAngleangle que doit atteindre la roue
steerAnglelimite maximale de rotation (ici 30°)

🎯 Ce que fait le script

➡️ À chaque fois que le joueur tourne :

  1. Le siège envoie une valeur (Steer)
  2. Le script multiplie cette valeur par 30
  3. Les roues avant tournent de cet angle

💬 En bref :

Quand tu tournes le volant, les roues tournent dans la même direction, comme une vraie voiture

Lance ton jeu pour vérifier le bon fonctionnement de ta direction :

Maintenant nous allons installer les roues.

Crée une roue centrée sur la direction de ta voiture, surélève ton châssis de voiture :

Renomme le part en « roue » :

Duplique en 4 roues :

Place tes 4 roues bien centrées :

Range tes roues dans l’arborescence de ta voiture :

Pour chaque roue positionne une charnière à partir du centre de la roue sur le centre de la direction :

Sélectionne les quatre HingeConstraint des quatre roues et applique ces propriétés :

Qu’est-ce qu’un HingeConstraint ?

Un HingeConstraint (en français : contrainte de charnière) relie deux objets pour qu’ils puissent tourner autour d’un axe, comme une porte sur ses gonds ou une roue sur son axe.

Sans moteur, il laisse juste la pièce tourner librement.
Avec un Motor, il fait tourner activement la pièce tout seul.

Quand ActuatorType = Motor

Alors le HingeConstraint se comporte comme un moteur qui fait tourner la pièce en continu 🌀

Les propriétés les plus importantes sont :

PropriétéRôle
AngularVelocityvitesse de rotation de la pièce (en radians/s)
MotorMaxTorqueforce maximum du moteur (plus elle est grande, plus il peut pousser)
AngularResponsivenessvitesse à laquelle le moteur s’adapte aux changements (réactivité)

Vérifie le sens de rotation :

Tu remarques que le sens gauche est inverse de celui du sens droit.

Vérifie le bon fonctionnement de la direction :

Modifie ton script :

local seat = script.Parent.VehicleSeat

local roueAvantGauche = script.Parent.RoueAvantGauche
local roueAvantDroite = script.Parent.RoueAvantDroite

local roueArriereGauche = script.Parent.RoueArriereGauche
local roueArriereDroite = script.Parent.RoueArriereDroite

local steerAngle = 30
local speed = 60

seat:GetPropertyChangedSignal("Steer"):Connect(function()
	print("Steer =", seat.Steer)
	roueAvantGauche.Direction.HingeConstraint.TargetAngle = 
                        steerAngle * seat.Steer
	roueAvantDroite.Direction.HingeConstraint.TargetAngle =
                        steerAngle * seat.Steer
end)

seat:GetPropertyChangedSignal("Throttle"):Connect(function()
	print("Throttle =", seat.Throttle)
	roueAvantGauche.Roue.HingeConstraint.AngularVelocity =
                        speed * seat.Throttle
	roueAvantDroite.Roue.HingeConstraint.AngularVelocity =
                        speed * -seat.Throttle

	roueArriereGauche.Roue.HingeConstraint.AngularVelocity =
                        speed * seat.Throttle
	roueArriereDroite.Roue.HingeConstraint.AngularVelocity =
                        speed * -seat.Throttle
end)

Ce script permet de faire tourner les roues d’une voiture quand le joueur accélère ou recule avec le clavier (les touches Z / S ou flèche haut / flèche bas).

🧩 Étape 1 : on récupère les objets importants

local seat = script.Parent.VehicleSeat

➡️ On récupère le siège de conduite de la voiture.
C’est lui qui détecte quand le joueur appuie pour avancer ou reculer.

local roueAvantGauche = script.Parent.RoueAvantGauche
local roueAvantDroite = script.Parent.RoueAvantDroite

local roueArriereGauche = script.Parent.RoueArriereGauche
local roueArriereDroite = script.Parent.RoueArriereDroite

➡️ On récupère les 4 roues du véhicule :

  • 2 à l’avant
  • 2 à l’arrière

Chaque roue contient un objet appelé HingeConstraint, une charnière qui permet à la roue de tourner sur elle-même.

🧩 Étape 2 : les réglages de base

local steerAngle = 30
local speed = 60
  • steerAngle : angle pour tourner (pas utilisé ici, mais utile si on veut tourner les roues plus tard).
  • speed : vitesse de rotation des roues (plus la valeur est grande, plus la voiture va vite 🚀).

🧩 Étape 3 : détecter quand le joueur accélère ou recule

seat:GetPropertyChangedSignal("Throttle"):Connect(function()

➡️ Cette ligne écoute la propriété « Throttle » du siège.
Elle change quand le joueur appuie sur :

  • Z / flèche hautThrottle = 1 → avancer 🏎️
  • S / flèche basThrottle = -1 → reculer 🚙
  • Rien → Throttle = 0 → arrêt ⛔

🧩 Étape 4 : faire tourner les roues

roueAvantGauche.Roue.HingeConstraint.AngularVelocity = speed * seat.Throttle
roueAvantDroite.Roue.HingeConstraint.AngularVelocity = speed * -seat.Throttle

🌀 Explication :

Chaque roue tourne grâce à sa vitesse angulaire (AngularVelocity), c’est-à-dire la vitesse à laquelle elle tourne autour de son axe.

Mais pourquoi une roue est multipliée par -seat.Throttle
👉 Parce que les roues droite et gauche sont dans des sens opposés (comme une vraie voiture).
Si elles tournaient dans le même sens, la voiture glisserait sur place au lieu d’avancer 😅.

Donc :

  • les roues de gauche tournent dans un sens,
  • celles de droite tournent dans le sens inverse,
    ➡️ ce qui fait avancer la voiture dans la bonne direction 🚗💨
roueArriereGauche.Roue.HingeConstraint.AngularVelocity = speed * seat.Throttle
roueArriereDroite.Roue.HingeConstraint.AngularVelocity = speed * -seat.Throttle

Même principe pour les roues arrière : elles tournent aussi pour propulser la voiture.

🧠 En résumé

ÉlémentRôle
VehicleSeatdétecte si le joueur accélère ou recule
Throttle-1 (reculer), 0 (ne bouge pas), 1 (avancer)
HingeConstraintfait tourner la roue
AngularVelocityvitesse de rotation de la roue
speeddéfinit la vitesse du véhicule
signe négatif -pour que les roues tournent dans le bon sens

🚗💨 En image (imagine) :

ToucheThrottleEffet
Z / ↑1roues tournent, voiture avance
S / ↓-1roues tournent en sens inverse, voiture recule
(rien)0roues s’arrêtent

Tu peux rouler avec ta voiture !!!!!!!!!!!!!

Catégories
ROBLOX

SYSTÈME DE GLISSADE


Création de l’animation glissade

Choisis AVATAR puis constructeur de RIG

Choisis ton RIG :

R6 : Moins de parties mobiles, mouvements moins fluides, apparence plus simple.

R15 : Plus de parties mobiles, mouvements plus fluides et réalistes, apparence plus détaillée.

Déplace ton RIG pour créer l’animation

Ouvre l’éditeur d’animation :

L’éditeur d’animation ouvre une Timelapse :

Une timelapse dans un éditeur d’animation est une technique qui permet de capturer et de montrer le processus de création d’une animation. Cela signifie que vous enregistrez votre travail à intervalles réguliers et ensuite vous compilez ces enregistrements en une vidéo qui montre l’ensemble du processus de l’animation.

Demande à créer l’animation sur l’ensemble du corps en appuyant sur le + :

Décoche Rotation et Déplacer

Modifie les positions du corps étape par étape pour animer une glissade :

Définis la priorité de l’animation :

Action2 : Utilisé pour les animations qui doivent avoir la priorité sur les animations d’inactivité et de mouvement, mais pas nécessairement sur les animations de haute priorité.

Sauvegarde l’animation et garde bien sa référence car tu vas en avoir besoin :

Copie la référence de l’animation :

Garde bien l’identifiant puis ferme la fenêtre:


Script de l’animation

Crée un localscript sous StarterPlayer dans StarterCharacterScripts :

Puis une animation :

Modifie les noms du script et de l’animation :

Tu peux maintenant coller la référence de l’animation dans AnimationId de ton animation :

Code script pour lancer l’animation :

Code ton script pour que l’animation se lance sur une touche du clavier, dans l’exemple la touche CTRL :

local UIS = game:GetService(« UserInputService »)


UIS.InputBegan:Connect(function(input, gpe)
if gpe then return end
if input.KeyCode == Enum.KeyCode.LeftControl then
print(« animation glissade »)
end
end)

Vérifie que tu as le message dans la sortie lorsque tu appuies sur CTRL

Code pour lancer l’animation dans une fonction et que tu ne puisses pas lancer plusieurs fois :

local in_progress = false
local function ActivationGlissade()
if not in_progress then
in_progress = true
print(« animation glissade »)
task.wait(1)
in_progress = false
end
end


UIS.InputBegan:Connect(function(input, gpe)
if gpe then return end
if input.KeyCode == Enum.KeyCode.LeftControl then
ActivationGlissade()
end
end)

Code pour lancer l’animation :

local UIS = game:GetService(« UserInputService »)

local Character = script.Parent
local Humanoid = Character:WaitForChild(« Humanoid »)
local GlissadeAnimation = Humanoid:LoadAnimation(script:WaitForChild(« GlissadeAnimation »))


local in_progress = false

local function ActivationGlissade()
if not in_progress then
in_progress = true
GlissadeAnimation:Play()
task.wait(1)
in_progress = false
end
end

Ton animation se lance mais ne s’arrête plus :

local function ActivationGlissade()
if not in_progress then
in_progress = true
GlissadeAnimation:Play()

local hipHeight = Humanoid.HipHeight
local walkSpeed = Humanoid.WalkSpeed
Humanoid.HipHeight = 0
Humanoid.WalkSpeed = 30

local BodyVelocity = Instance.new(« BodyVelocity »)
BodyVelocity.MaxForce = Vector3.new(1, 0, 1) * 10000
BodyVelocity.Velocity = Character.HumanoidRootPart.CFrame.LookVector * 30
BodyVelocity.Parent = Character.HumanoidRootPart


task.wait(1)

GlissadeAnimation:Stop()
Humanoid.HipHeight = hipHeight
Humanoid.WalkSpeed = walkSpeed
BodyVelocity:Destroy()

in_progress = false

end
end

Modifie ton code pour paramétrer le temps de l’animation et sa vitesse :



local function ActivationGlissade(sliding_time, speed)

Humanoid.WalkSpeed = speed
BodyVelocity.Velocity = Character.HumanoidRootPart.CFrame.LookVector * speed
task.wait(sliding_time)



ActivationGlissade(0.5,10)

fin

Catégories
ROBLOX

Crée ton premier jeu OBBY

Créer un OBBY

Dans l’univers de Roblox, un « Obby » (abréviation de « Obstacle Course », ou parcours d’obstacles en français) est un type de jeu très populaire où les joueurs doivent traverser une série d’obstacles de plus en plus difficiles pour atteindre la fin du parcours. Voici ce qui caractérise un Obby et pourquoi ce genre est si apprécié :

1. Principe de base

  • Objectif : Le but est de terminer le parcours en évitant ou en surmontant tous les obstacles (sauts, plateformes mobiles, pièges, etc.).
  • Difficulté progressive : Les niveaux deviennent généralement plus difficiles au fur et à mesure que le joueur avance.

2. Types d’obstacles courants

  • Sauts de précision : Plateformes étroites ou éloignées les unes des autres.
  • Pièges : Lames, trous, obstacles en mouvement, etc.
  • Mécaniques uniques : Portails, téléporteurs, gravité inversée, etc.
  • Défis temporels : Certains Obby imposent une limite de temps pour chaque section.

3. Pourquoi les Obby sont-ils populaires ?

  • Accessibilité : Faciles à comprendre, mais difficiles à maîtriser, ce qui les rend adaptés à tous les niveaux de joueurs.
  • Créativité : Les créateurs de Roblox peuvent concevoir des parcours très variés, avec des thèmes et des mécaniques uniques.
  • Compétition : Les joueurs aiment se mesurer les uns aux autres en termes de temps ou de capacité à terminer le parcours.
  • Récompenses : Certains Obby offrent des badges, des objets virtuels ou de la monnaie en jeu pour les joueurs qui les terminent.

4. Exemples de mécaniques avancées

  • Checkpoints : Points de sauvegarde pour éviter de recommencer depuis le début après une chute.
  • Power-ups : Objets spéciaux qui aident le joueur (double saut, vitesse accrue, etc.).
  • Thèmes variés : Univers futuristes, médiévaux, horreur, etc.

5. Comment en créer un ?

  • Dans Roblox Studio, les créateurs utilisent des parts (blocs), des scripts (pour les pièges ou mécaniques avancées) et des outils de terrain pour construire leur Obby.
  • La communauté Roblox partage souvent des tutoriels et des modèles 3D pour aider les nouveaux créateurs.

En résumé, un Obby est un jeu de plateforme et d’adresse où le défi et la créativité sont au cœur de l’expérience. Si vous voulez essayer, il existe des milliers d’Obby gratuits sur Roblox, allant du très simple au extrêmement difficile !

Critères :

  1. Créer un monde : Votre obby doit vous ressembler.
  2. Créer des obstacles : Utiliser les parts de Roblox ou des objets graphiques extérieurs.
  3. Créer des pièges et des mécanismes : piège mortel, portail …
  4. Ne pas utiliser la tool-box : Évitez d’utiliser la tool-box pour les scripts et certains obstacles.

Prise en main de ROBLOX :

https://youtu.be/tlW5GhxaxU0?si=tTUrljHe90H0n0Pa
https://youtu.be/ZVmbdibGcMM?si=_bMmYn8U9zYAsWbp

Explications plus techniques


Partie 01 : Créer un Lobby

Objectif : Créer un lobby (zone de départ) où le joueur apparaîtra et le décorer.

Dans un jeu Roblox, et notamment dans un Obby, le « lobby » (ou hall d’entrée en français) est une zone essentielle qui sert de point de départ et de rassemblement pour les joueurs avant qu’ils ne commencent le parcours ou le jeu proprement dit.

Exemple d’un lobby

  • Dans un Obby, le lobby peut ressembler à une petite île, une salle ou une plateforme avec un grand panneau « Start » ou « Commencer ». Les joueurs cliquent sur ce panneau (ou marchent dessus) pour être téléportés au début du parcours d’obstacles.

Crée une île

Pour créer un projet avec le modèle Baseplate :

  1. Dans la barre de navigation verticale, sélectionne « Modèles » . Tous les modèles s’affichent.
  2. Sélectionnez le modèle « Baseplate » . Roblox Studio ouvre une nouvelle expérience :

Apprend maintenant à utiliser l’éditeur de terrain pour créer un environnement insulaire autour du lieu d’apparition, départ de ton futur jeu de plateformes.

Crée une île avec l’éditeur de création de terrain

Dans la barre de menu, accède à l’ onglet Accueil , puis clique sur le bouton Éditeur de terrain . La fenêtre Éditeur de terrain s’affiche :

Dans la fenêtre Éditeur de terrain , clique sur l’ onglet Editer, puis sur le bouton Dessiner :

Dans les sections Paramètres de la brosse et Paramètres du matériel , choisis les options suivantes  :

Règle la taille de la brosse :

  • Puis choisi comme matériel l’herbe :

Puis dessine ton ile :

Sélectionne dans la fenêtre Explorateur sous Workspace : SpawLocation puis modifie sa position : y = 13

Si tu joues, tu parcours ton île dans l’herbe.

Mais ton île n’en n’est pas vraiment une, il manque l’eau autour.

Deux possibilités, soit tu génères l’océan par un script , ainsi tu pourras gérer le niveau de l’océan, soit tu le dessines.

Générer l’océan par script

crée un script sous workspace en utilisant le + à droite de workspace puis choisis script :

local terrain = workspace.Terrain
-- Configuration
local NIVEAU_MER = 202 -- La hauteur Y de la surface de l'eau
local TAILLE_CARTE = 2048 -- La taille de la zone en X et Z (studs)
local PROFONDEUR = 200 -- Jusqu'où l'eau descend
function updateSeaLevel(hauteurSurface)
	-- Calculer le centre et la taille du bloc d'eau
	-- On veut que le haut du bloc soit à 'hauteurSurface'
	local fond = hauteurSurface - PROFONDEUR
	local centreY = (hauteurSurface + fond) / 2
	local tailleY = hauteurSurface - fond

	local cframe = CFrame.new(0, centreY, 0)
	local size = Vector3.new(TAILLE_CARTE, tailleY, TAILLE_CARTE)

	-- Remplir la zone avec de l'eau
	-- Enum.Material.Water est le matériau liquide
	terrain:FillBlock(cframe, size, Enum.Material.Water)
end
-- Appeler la fonction au lancement
updateSeaLevel(NIVEAU_MER)

Ou dessine un océan

Crée un océan autour de ton île, choisis dans l’éditeur de terrain l’outil Remplir puis modifie les Paramètres de sélection puis les Paramètres du matériel taille X : 4000 Y: 8 Z : 4000, position X : 0, Y : 4, Z : 0 :

Sélectionne Air dans le Matériel source :

Puis choisis dans le Matériel cible l‘Eau puis Remplacer :

Maintenant tu obtiens une vraie île, tu peux supprimer la Baseplate dans la fenêtre Explorateur:

Maintenant tu parcourir ton monde et prendre un bain :

Suggestion pour la suite

Pour t’aider, n’oublie pas d’utiliser la fenêtre de sortie pour debugger tes scripts en affichant des traces ou le contenu de variables :

N’hésite pas à mettre des commentaires dans tes scripts :

Commentaire d’une ligne :

— commentaire sur une ligne

Commentaire de plusieurs instructions :

–[[
commentaire sur plusieurs lignes
commentaire sur plusieurs lignes
–]]


Partie 02 : Crée tes plateformes

Avant d’insérer des éléments d’espace réservé dans l’espace 3D, il est important de créer une structure d’organisation pour tes ressources dans le Workspace . Ce processus garantit que ton espace de travail reste organisé et facile à analyser.

Il existe deux types de conteneurs que tu peux utiliser pour regrouper des ressources : les objets Folder et Modèle . Les dossiers sont utiles pour stocker de nombreux objets de différents types, et les modèles sont utiles pour stocker des groupements géométriques de pièces similaires. Les instructions suivantes t’apprenne à utiliser les deux objets conteneurs pour stocker toutes les ressources de ton monde 3D.

Pour créer une structure organisationnelle :

  1. Dans la fenêtre de l’Explorateur , passe la souris sur Workspace et cliquez sur l’ icône ⊕ . Un menu contextuel s’affiche.
  2. Dans le menu contextuel, insérez un objet Folder :

Renomme le nouveau dossier « World » .

  1. Clique avec le bouton droit sur l’objet dossier. Un menu contextuel s’affiche.
  2. Dans le menu contextuel, clique sur Renommer et entrez World comme nom du dossier :

Puis crée une structure Model pour toutes tes plateformes :

Puis renomme ton Model en plateformes :

Maintenant que tu disposes d’une structure pour contenir tes plateformes, tu vas insèrer des éléments 3D pour représenter tes plateformes :

Pour insérer une pièce cylindrique pour ta première plateforme :

  1. Dans la barre de menu, sélectionnez l’onglet Accueil .
  2. Dans la section Elément Insérer , clique sur la flèche déroulante, puis sélectionnez Cylindre . Une pièce cylindrique s’affiche dans la fenêtre d’affichage :

Puis glisse le nouvel objet sous le Folder World :

Puis renomme l’objet cylindre :

Saisie la taille et la position de ta première plateforme :

Dans la fenêtre de l’Explorateur , sélectionnez le modèle Plateformes.

Dans l’ onglet Accueil , accédez à la section Modifier et cliquez sur l’icône Ancre . Cela garantit que le système physique ne déplace pas les plateformes lorsque l’on joue.

Tu peux vérifier :

Lance ton jeu et saute sur ta première plateforme :

Par un clique droit demande à dupliquer ta première plateforme, recommence l’opération pour obtenir trois plateformes :

Puis modifie la taille et la position des deux nouvelles plateformes :

Tu dois obtenir ce résultat :


Partie 03 : Crée un menu à ton joueur pour déplacer un part

Objectif : Créer un système pour déplacer une part à droite, à gauche, en haut, vers le bas.

Instructions :

  1. Créer une part : Ajoutez une part et renommez-la.
  2. Créer un « Screen Gui » : Dans « StarterGui », ajoutez un « Screen Gui » et placez une « Frame » à l’intérieur.
  3. Système d’ouverture/fermeture : Créez deux boutons pour ouvrir et fermer la « Frame ».
  4. Boutons de déplacement : Ajoutez quatres boutons pour déplacer la part à droite et à gauche, haut et bas.

Comment indiquer une ressource dans un script :

local openButton = script.Parent.QuitButton

Comment détecter un click de la souris sur un bouton :

openButton.MouseButton1Click:Connect(function()

end)

Programmation pour ouvrir ou fermer la fenêtre de contrôle dans un LocalScript :

local controFrame = script.Parent.Parent:WaitForChild("ControlFrame")
local openButton = script.Parent
local closeButton = controFrame.QuitButton

-- Ouverture de la fenêtre de contrôle
openButton.MouseButton1Click:Connect(function()
	controFrame.Visible = not controFrame.Visible
	openButton.Visible = false
end)

-- Fermeture de la fenêtre de contrôle	
closeButton.MouseButton1Click:Connect(function()
	controFrame.Visible = not controFrame.Visible
	openButton.Visible = true
end)

downButton.MouseButton1Click:Connect(function()
	myPart.Position += Vector3.new(0,-2,0)
end)

controFrame.Visible = false
myPart.Anchored = true

Comment déplacer un objet Roblox :

myPart.Position += Vector3.new(10,0,0)

Exemple de code pour déplacer le part en modifiant ton localScript :

local controFrame = script.Parent.Parent:WaitForChild("ControlFrame")
local openButton = script.Parent
local closeButton = controFrame.QuitButton

local downButton = controFrame.DownButton
local leftButton = controFrame.LeftButton
local rightButton = controFrame.RightButton
local upButton = controFrame.UpButton

local myPart = game.Workspace:WaitForChild("MyPart")

-- Ouverture de la fenêtre de contrôle
openButton.MouseButton1Click:Connect(function()
	controFrame.Visible = not controFrame.Visible
	openButton.Visible = false
end)

-- Fermeture de la fenêtre de contrôle	
closeButton.MouseButton1Click:Connect(function()
	controFrame.Visible = not controFrame.Visible
	openButton.Visible = true
end)

-- Déplacement du part
leftButton.MouseButton1Click:Connect(function()
	myPart.Position += Vector3.new(-10,0,0)
end)

rightButton.MouseButton1Click:Connect(function()
	myPart.Position += Vector3.new(10,0,0)
end)

upButton.MouseButton1Click:Connect(function()
	myPart.Position += Vector3.new(0,2,0)
end)

downButton.MouseButton1Click:Connect(function()
	myPart.Position += Vector3.new(0,-2,0)
end)

controFrame.Visible = false
myPart.Anchored = true

Partie 04 : Crée un Chat au joueur

Comment gérer un message d’indication au joueur par un Chat :

Rajouter un ModuleScript ChatScript sous ReplicatedStorage :

Puis coder dans ce script :

local ChatScript = {}

function ChatScript.sendMessage(player, message)

local character = player.Character or player.CharacterAdded:Wait()
if character then
    local head = character:WaitForChild("Head") 
    if head then
        game:GetService("Chat"):Chat(head, message) 
    end
end

end

return ChatScript

Rajouter dans votre script qui gère votre interface les instructions suivantes lorsque le joueur referme la fenêtre :

— récupération du service de chat
local chat = require(game.ReplicatedStorage.ChatScript)

— récupération du player dans un localScript
local player = game:GetService(« Players »).LocalPlayer

chat.sendMessage(player, "niveau : 1")

Partie 05 : Fais bouger les plateformes

Objectif : Faire en sorte qu’une ou plusieurs parts bougent continuellement.

Instructions :

  1. Ajouter des parts mobiles : Dans un de vos niveaux, ajoutez des parts qui bougent.
    • Indice : Utilisez while true do et for i = 1, x do pour créer un mouvement continu.

Déplacer un objet x fois :

for i = 1, 50 do
maPart.Position += Vector3.new(5,0,0)
wait(1)
end

Déplacer un objet Roblox tout le temps :

while true do
maPart.Position += Vector3.new(0.05,0,0)
wait(0.01)
end

Déplacer un objet jusqu’à une position :

while maPart.Position.X<60 do
maPart.Position += Vector3.new(5,0,0)
wait(0.01)
end

Synchroniser le déplacement avec le moteur de Roblox :

game:GetService(« RunService »).Heartbeat:Connect(function()
maPart.Position += Vector3.new(0.05,0,0)
end)

Exercer une force sur le part pour le bouger :

local part = script.Parent

part.Anchored = false

task.wait(5)
part.AssemblyLinearVelocity = Vector3.new(0, 0, 100)
task.wait(1)
part.AssemblyLinearVelocity = Vector3.new(0, 0, -100)
task.wait(1)
part.AssemblyAngularVelocity = Vector3.new(0, 10, 0)
task.wait(1)
part.AssemblyAngularVelocity = Vector3.new(0, -10, 0)
task.wait(1)
part.AssemblyLinearVelocity = Vector3.new(0, 100, 0)
task.wait(1)
part.AssemblyLinearVelocity = Vector3.new(0, 100, 100)
part.AssemblyAngularVelocity = Vector3.new(0, 10, 0)

Déplace un part et monte dessus pour te déplacer :

local part = script.Parent

local distance = 100
local speed = 5
local index = 0

part.Anchored = false

-- Fonction appelée à chaque frame pour déplacer les plateformes
local function movementPart(deltaTime)

	if deltaTime > 0 then
		part.AssemblyLinearVelocity = Vector3.new(0, 0, speed)
		index += speed * deltaTime
		print(index, speed, deltaTime)
		if index >= distance then
			speed = speed * -1
		end
		if index <= 0 then
			speed = speed * -1
		end
	end

end

-- On écoute l'événement Heartbeat 
-- pour déclencher le mouvement du part
local RunService = game:GetService("RunService")
RunService.Heartbeat:Connect(movementPart)

Partie 06 : Crée un système de plateformes mobiles

Crée une plateforme par Modèle Elément Bloc :

Glisse ce nouvel objet sous le folder World puis le Model Platforms

:

Dimensionne et place ta plateforme mobile dans l’espace de ton jeu :

Puis choisis de créer un nouvel attribut par le + dans les propriétés de la plateforme mobile :

Puis donne la valeur du déplacement soit sur l’axe X ou Y ou Z :

Crée un nouveau script dans ServerScriptService, puis renomme en mobilePlatformsScript:

Dans le script rajoute cette programmation :

local RunService = game:GetService("RunService")

-- Configuration
local DEFAULT_SPEED = 0.5

local platforms         = script.Parent
local platformChildren  = platforms:GetChildren()

-- Cache des données par platform (évite GetAttribute à chaque frame)
local platformData = {}

-- Initialisation
for _, platform in ipairs(platformChildren) do
	if not platform:IsA("BasePart") then continue end

	local movement = platform:GetAttribute("movement")
	if not movement then continue end

	local speed = platform:GetAttribute("speed") or DEFAULT_SPEED

	platform:SetAttribute("StartPosition", platform.Position)
	platform.Anchored = true

	-- Stocke les données en mémoire
	platformData[platform] = {
		movement      = movement,
		speed         = speed,
		startPosition = platform.Position,
	}
end

-- Déplacement de chaque plateforme
local function movePlatform(platform, data, deltaTime)
	--[[
	On veut un nombre qui monte et descend tout seul entre 0 et 1, en boucle, 
	pour faire bouger la plateforme d'un point A à un point B et revenir.
	la fonction math.sin est une fonction mathématique qui produit une vague naturelle
	qui oscille entre -1 et 1. En ajoutant 1, on l'adoucit entre 0 et 2.
	Diviser par 2 donne une valeur entre 0 et 1.
	]]
	-- Sinus pour un mouvement naturel	
	local alpha       = (math.sin(time() * data.speed) + 1) / 2
	-- Interpolation entre la position de départ et le déplacement défini
	local newPosition = data.startPosition:Lerp(data.startPosition + data.movement, alpha)

	-- Vélocité physique pour que le joueur suive la plateforme
	if deltaTime > 0 then
		platform.AssemblyLinearVelocity = (newPosition - platform.Position) / deltaTime
	end

	platform.CFrame = CFrame.new(newPosition)

end

-- Boucle de rendu 60 FPS (ou plus) via Heartbeat pour les déplacements des plateformes 
RunService.Heartbeat:Connect(function(deltaTime)
	for platform, data in pairs(platformData) do
		-- Vérifie que la plateforme existe encore
		if not platform or not platform.Parent then
			platformData[platform] = nil
			continue
		end
		movePlatform(platform, data, deltaTime)
	end
end)

Crée une plateforme type ascenseur

Crée un nouveau bloc au dimension de ton ascenseur :

Puis glisse ce nouveau bloc dans l’explorateur sous Platforms puis renomme Elevator :

Puis créé deux nouveaux attributs movement et speed pour son déplacement vertical :


Partie 07 : Crée une plateforme mortelle

Objectif : Créer une part qui tue le joueur lorsqu’il la touche.

Instructions :

  1. Créer un part rouge : Ajoutez un part, colorez-le en rouge et utilisez le matériau « Néon ».
  1. Ajouter un script : Créez un script dans le part.
  2. Script de mort : Lorsque le joueur touche le part, il meurt.
    • Indices :
      • Utilisez [Nom du part].Touched:Connect(function(player) pour détecter le contact.
      • Utilisez character = player.Parent pour obtenir le personnage du joueur.
      • Utilisez humanoid = character and character:FindFirstChild("Humanoid") pour obtenir l’objet Humanoid du joueur.
      • Tuer le joueur : humanoid.Health = 0

Santé du joueur à 100 au départ du jeu :

print(humanoid.Health)

Réduire la santé du joueur :

humanoid.Health = humanoid.Health – 5
ou
humanoid:TakeDamage((5))

Le joueur meurt quand sa santé est à zéro :

humanoid.Health = 0

Un exemple de code avec une mort rapide :

local deadlyPart = script.Parent

deadlyPart.Touched:Connect(function(player)
	local character = player.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if humanoid then
		humanoid.Health = humanoid.Health - 5
	end
end)

Un exemple de code avec une mort lente :

local deadlyPart = script.Parent
local startTime = 0


deadlyPart.Touched:Connect(function(player)
	local character = player.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if humanoid then
		if startTime > 0 and (tick() - startTime) > 0.2 then
			startTime = 0
		end
		if startTime == 0 then
			print(humanoid.Health)
			humanoid.Health = humanoid.Health - 5
			startTime = tick()
		end
	end
end)

Partie 08 : Rend une plateforme invisible avec un clickDetector ou ProximityPrompt

Objectif : Créer un part invisible qui apparaît lorsque le joueur clique sur un autre part avec un clickDetector.

Instructions :

  1. Créer un part avec ClickDetector : Ajoutez un part, renommez-la, et ajoutez un « ClickDetector ».
  2. Créer un part invisible : Ajoutez un autre part et définissez Transparency = 1 et CanCollide = false.
  3. Script d’apparition : Lorsque le joueur clique sur le part avec le « ClickDetector », le deuxième part apparaît.
    • Indices :
      • Utilisez myClickDetector.MouseClick:Connect(function() pour détecter le clic.

Comment coder un ClickDetector sur le part :

local myFirstPart = script.Parent
local clickDetector = myFirstPart.ClickDetector
local mySecondPart =myFirstPart.MySecondPart

clickDetector.MouseClick:Connect(function()
	mySecondPart.Transparency=0
end)

Objectif : Créer un part invisible qui apparaît lorsque le joueur clique sur un autre part avec un proximityPrompt :

Comment coder un ProximityPrompt sur le part

local myFirstPart = script.Parent
local proximity = myFirstPart.ProximityPrompt
local mySecondPart =myFirstPart.MySecondPart

proximity.Triggered:Connect(function(player)
	mySecondPart.Transparency=0
end)

Partie 09 : Pathfinding (recherche de chemin) avec des Parts

Objectif : Créer un chemin de parts où le joueur doit sauter au bon moment pour passer à la prochaine part.

Instructions :

  1. Créer 3 parts : Ajoutez des parts et renommez-les.
  2. Créer deux niveaux de chemin : Disposez les parts de manière à ce que le joueur doive sauter de part en part puis cliquer pour passer au niveau suivante.
    • Indice : Utilisez la Transparency pour rendre les parts invisibles du chemin.

Exemple de Pathfinding avec deux niveaux :

Exemple pour passer à un niveau 2 :

Exemple de script pour faire apparaître le niveau 2 lors du clic sur le ClickDetector:

local clickDetector = script.Parent.Level01.ArrowToLevel02.ClickDetector

-- récupération de tous les parts du niveau 2
local levels = script.Parent.Level02:GetChildren()

-- récupération du système de chat
local chat = require(game.ReplicatedStorage.ChatScript)

clickDetector.MouseClick:Connect(function(otherPart)

	-- envoie du message au chat du joueur
	chat.sendMessage(otherPart, "niveau : 2")

	-- rendre visible tous les objets du niveau 2 
	for _, level in levels do
		level.Transparency = 0
	end
end)

Partie 10 : Crée un système de zones de danger

Crée des zones de danger qui vont réduire la santé des joueurs lorsqu’ils les touchent. Pour commencer, apprend à créer une grande partie invisible au niveau de l’eau, de sorte que tomber dans celle-ci entraine la disparition du joueur et le fasse recommencer au début du jeu.

Pour créer cette zone de danger :

  1. Dans la fenêtre de l’Explorateur , ajoute un nouveau dossier dans le dossier Monde , puis renomme-le : Hazards .
  2. Dans le dossier Hazards , insére une partie bloc et renomme-la Hazard :

Sur le + à droite de World demande à insérer un Model :

Puis renomme ce model en Hazards :

Puis dans l’onglet MODELE, demande un nouveau Elément Bloc :

Puis glisse ce nouvel objet sous Hazards :

Renomme le Hazard :

Déplace et met à l’échelle la zone de danger pour couvrir l’eau autour des plates-formes. Par exemple, avec ces données :

Puis modifie ces propriétés pour que la zone de danger soit invisible et que les joueurs puissent le traverser :

Règle la transparence sur 1. Cela rend le danger invisible, de sorte que l’eau réelle semble être le danger:

Désactive CanCollide . Cela indique au moteur ROBLOX que les autres parties peuvent traverser le danger sans interruption, ce qui signifie que les joueurs peuvent tomber à travers le danger.

Active Ancre . Cela indique au moteur ROBLOX de ne jamais modifier la position de la zone de danger.

Crée un script dans ServerScriptService , puis renommez-le en HazardService :

Remplace le code par défaut par le code suivant :

local workspace = game:GetService("Workspace")
local hazards = workspace.World.Hazards:GetChildren()

local function onHazardTouched(player, hazard)
	if not hazard:GetAttribute("Enabled") then
		return
	end
	local character = player.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if humanoid then
		humanoid.Health = 0
	end

end

for _, hazard in hazards do
	hazard:SetAttribute("Enabled", true)
	hazard.Touched:Connect(function(player)
		onHazardTouched(player, hazard)
	end)
end

Joue et tombe dans l’eau autour des plateformes :

Rajoute des animations sur les zones de danger

Mettre le feu

Installe une zone où un incendie se déclenche aléatoirement, à ne pas traverser au péril de perdre une vie.

Dans la boîte à outil recherche une animation d’un feu : fire :

Sélectionne l’animation Realistic Fire With Smoke, un feu avec de la fumée. Puis glisse cette animation sous Hazards :

Positionne ton incendie à un endroit stratégique de ton jeu :

Modifie le script HazardService en ajoutant cette programmation qui va sur un intervalle de temps aléatoire allumer ou éteindre le feu en rendant ainsi la zone dangereuse ou pas.

local workspace = game:GetService("Workspace")
local hazards = workspace.World.Hazards:GetChildren()

local function onHazardTouched(player, hazard)
	if not hazard:GetAttribute("Enabled") then
		return
	end
	local character = player.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if humanoid then
		humanoid.Health = 0
	end

end

for _, hazard in hazards do
	hazard:SetAttribute("Enabled", true)
	hazard.Touched:Connect(function(player)
		onHazardTouched(player, hazard)
	end)
end

local runService = game:GetService("RunService")
local interval = math.random(5, 10)

local function updateFire()
	for _, hazard in hazards do
		local fire = hazard:FindFirstChildOfClass("ParticuleEmitter")
		if fire then
			fire.Enabled = not fire.Enabled
			hazard.SetAttribut("Enabled", fire.Enabled)
		end
	end
end

Le joueur doit attendre la fin de l’incendie pour pouvoir passer.

Si tu le souhaites, tu peux installer plusieurs zones de feu dans ton jeu :

Une explosion

Rajoute un bloc sous Hazards et renomme le Explosion :

Puis utilise le + à droite de Explosion pour rajouter ParticleEmitter :

Que tu renommes Explosion :

Puis modifie les propriétés suivantes :

Teste le résultat et reviens sur les paramètres pour obtenir le résultat que tu souhaites :

Puis rends le socle transparent et canCollide à False :

Recommence pour une nouvelle zone de danger avec ce nouvel effet comme celui-ci :

Trouve les bons paramètres.


Partie 11 : Des portes à ouvrir

Objectif : Créer un labyrinthe avec des portes à ouvrir

Ouvrir une porte avec un bouton poussoir :

Construis une porte avec un bouton poussoir pour l’ouverture :

Avec un ClickDetector sur le bouton :

Intercepter le click sur le ClikDetector dans le script :

-- Récupération de la porte
local door = script.Parent
-- Récupération du clickDetector
local clickDetector = door.PushButton.ClickDetector

clickDetector.MouseClick:Connect(function(player)
	print("Le joueur "..player.Name, 
			"a demandé l'ouverture de la porte")
end)

Lance le jeu et click sur le bouton poussoir, un message s’affiche dans la sortie :

Puis modifie ton script pour « ouvrir la porte » en rendant invisible la Part de la porte :

-- Récupération de la porte
local door = script.Parent
-- Récupération du clickDetector
local clickDetector = door.PushButton.ClickDetector

clickDetector.MouseClick:Connect(function(player)
	print("Le joueur "..player.Name, 
		"a demandé l'ouverture de la porte")
	door.Door.Transparency = 1
end)

Mais tu peux constater que le joueur ne passe pas la porte, pour éviter ce problème tu peux éviter la collision entre la porte et le joueur :

-- Récupération de la porte
local door = script.Parent
-- Récupération du clickDetector
local parts= door:GetChildren()

function openDoor(player)
	print("Le joueur "..player.Name, 
		"a demandé l'ouverture de la porte")
	door.Door.Transparency = 1
	door.Door.CanCollide = false
end

Deux possibilités pour refermer la porte :

  • un autre click par le joueur
-- Récupération de la porte
local door = script.Parent
-- Récupération du clickDetector
local clickDetector = door.PushButton.ClickDetector

clickDetector.MouseClick:Connect(function(player)
	print("Le joueur "..player.Name, 
		"a demandé l'ouverture de la porte")
	if door.Door.CanCollide then
		door.Door.Transparency = 1
	else
		door.Door.Transparency = 0
	end
	door.Door.CanCollide = not door.Door.CanCollide
end)
  • fermeture automatique après un certain temps
-- Récupération de la porte
local door = script.Parent
-- Récupération du clickDetector
local clickDetector = door.PushButton.ClickDetector

clickDetector.MouseClick:Connect(function(player)
	print("Le joueur "..player.Name, 
		"a demandé l'ouverture de la porte")
	door.Door.Transparency = 1
	door.Door.CanCollide = false
	
	task.wait(2)
	
	door.Door.Transparency = 0
	door.Door.CanCollide = true

end)

Ouverture de la porte avec deux boutons poussoirs :

Comment faire si deux boutons poussoirs de chaque coté de la porte :

-- Récupération de la porte
local door = script.Parent
-- Récupération du clickDetector
local parts= door:GetChildren()

function openDoor(player)
	print("Le joueur "..player.Name, 
		"a demandé l'ouverture de la porte")
	if door.Door.CanCollide then
		door.Door.Transparency = 1
	else
		door.Door.Transparency = 0
	end
	door.Door.CanCollide = not door.Door.CanCollide

end

-- récupération de tous les clickDetectors
for _, part in ipairs(parts) do
	local clickDetector = 
              part:FindFirstChild("ClickDetector")
	if clickDetector then
		clickDetector.MouseClick:Connect(function(player)
			openDoor(player)
		end)
	end
end

Fermeture automatique de la porte

Comment refermer la porte automatiquement au bout d’un laps de temps :

-- Récupération de la porte
local door = script.Parent
-- Récupération du clickDetector
local parts= door:GetChildren()

function closeDoor()
	task.wait(2)
	if not door.Door.CanCollide then
		door.Door.Transparency = 0
		door.Door.CanCollide = true
	end
end	
	
function openDoor(player)
	print("Le joueur "..player.Name, 
		"a demandé l'ouverture de la porte")
	if door.Door.CanCollide then
		door.Door.Transparency = 1
		task.spawn(closeDoor)
	else
		door.Door.Transparency = 0
	end
	door.Door.CanCollide = not door.Door.CanCollide

end

-- récupération de tous les clickDetectors
for _, part in ipairs(parts) do
	local clickDetector = part:FindFirstChild("ClickDetector")
	if clickDetector then
		clickDetector.MouseClick:Connect(function(player)
			openDoor(player)
		end)
	end
end

Ouvrir une porte par une zone de détection :

Crée un part invisible autour de la porte qui aura la fonction d’une zone de détection de l’entrée ou la sortie du joueur :

Modifie les propriétés de la zone de détection

Supprime l’option de la possibilité de la collision :

Rend transparent la zone de collision :

Et évidement ancre la zone de détection :

Modifie le script pour détecter l’entrée et la sortie du joueur de la zone de détection :

-- Récupération de la porte
local door = script.Parent
local detectionZone = door.DetectionZone
-- Le joueur rentre dans la zone de détection
detectionZone.Touched:Connect(function()
	print("entrée")
end)
-- Le joueur sort de la zone de détection
detectionZone.TouchEnded:Connect(function()
	print("sortie")
end)

Ouvrir et fermer la porte avec la détection du joueur :

-- Récupération de la porte
local door = script.Parent
local detectionZone = door.DetectionZone

-- Le joueur rentre dans la zone de détection
detectionZone.Touched:Connect(function()
	print("entrée")
	if door.Door.CanCollide then
		door.Door.Transparency = 1
		door.Door.CanCollide = false
	end
end)

-- Le joueur sort de la zone de détection
detectionZone.TouchEnded:Connect(function()
	print("sortie")
	if not door.Door.CanCollide then
		door.Door.Transparency = 0
		door.Door.CanCollide = true
	end
end)

Rajoute une temporisation avant la fermeture de la porte pour éviter des ouvertures et des fermetures intempestives quand le joueur reste sur le bord de la zone de détection :

-- Récupération de la porte
local door = script.Parent
-- Récupération de la zone de détection
local detectionZone = door.DetectionZone
-- Temps d'attente avant fermeture de la porte
local TIMEOUTCLOSE = 2

-- Le joueur rentre dans la zone de détection
detectionZone.Touched:Connect(function()
	print("entrée")
	if door.Door.CanCollide then
		door.Door.Transparency = 1
		door.Door.CanCollide = false
	end
end)

-- Le joueur sort de la zone de détection
detectionZone.TouchEnded:Connect(function()
	print("sortie")
	if not door.Door.CanCollide then
		task.spawn(function()
			door.Door.CanCollide = true
			task.wait(TIMEOUTCLOSE)
			if door.Door.CanCollide then
				door.Door.Transparency = 0
			end
		end)
	end
end)

Rajouter un son d’ouverture

Ouvrir la boîte à outils pour trouver un son d’ouverture de porte :

Choisir Audio :

Saisir une recherche :

Choisir un son pour le mettre dans l’arborescence du workspace de la porte :

Puis modifie le script pour rajouter le son lors de l’ouverture de la porte :

-- Récupération de la porte
local door = script.Parent
-- Récupération de la zone de détection
local detectionZone = door.DetectionZone
-- Temps d'attente avant fermeture de la porte
local TIMEOUTCLOSE = 2
local soundDoor = door.door_open

-- Le joueur rentre dans la zone de détection
detectionZone.Touched:Connect(function()
	print("entrée")
	if door.Door.CanCollide then
		soundDoor:Play()
		door.Door.Transparency = 1
		door.Door.CanCollide = false
	end
end)

-- Le joueur sort de la zone de détection
detectionZone.TouchEnded:Connect(function()
	print("sortie")
	if not door.Door.CanCollide then
		task.spawn(function()
			door.Door.CanCollide = true
			task.wait(TIMEOUTCLOSE)
			if door.Door.CanCollide then
				door.Door.Transparency = 0
			end
		end)
	end
end)

Ouvrir une porte par une rotation :

Créez une porte à partir d’un part :

Rangez le part et renommez le dans l’explorateur :

Puis créez avec un part une poignée :

Créez une contrainte rigide entre la porte et la poignée :

Sélectionnez la poignée puis la porte puis demande une « soudure » entre les deux éléments :

Demandez un clickDetector sur la poignée :

Modifiez le pivot de la porte :

Créez un script pour ouvrir la porte :

-- Récupération du clickDetector
local clickDetector = script.Parent.Handle.ClickDetector
-- Récupération de la porte
local door = script.Parent.Door
-- Récupération de la distance d'activation du clickdetector
local distance = clickDetector.MaxActivationDistance

-- Fonction de rotation de la porte
local function doorRotation(door, push, rotation)
clickDetector.MaxActivationDistance = 0
if push ~= 0 then
for i = 1, (rotation//math.abs(push)) do
door:PivotTo(door:GetPivot() *
CFrame.Angles(0, math.rad(push), 0))
wait(0.01)
end
end
clickDetector.MaxActivationDistance = distance
end

-- Fonction de détection de clic di clickdetector
clickDetector.MouseClick:Connect(function()
doorRotation(door, 1, 90)
end)
end


Refermez la porte au bout de x secondes, rajouter ces deux instructions :
-- Fonction de détection de clic
clickDetector.MouseClick:Connect(function()
	doorRotation(door, 1, 90)
	task.wait(5)
	doorRotation(door, -1, 90)
end)

Modifier le script pour un déplacement de la porte vers le haut :

local clickDetector = script.Parent.Handle.ClickDetector
local door = script.Parent.Door

local distance = clickDetector.MaxActivationDistance

local function doorPushUp(door, push)
	door.CFrame += Vector3.new(0,push,0)
	while door.CFrame.Position.Y>5 and door.CFrame.Position.Y<15   do
		wait(0.01)
		door.CFrame += Vector3.new(0,push,0)
	end
end

clickDetector.MouseClick:Connect(function()
	clickDetector.MaxActivationDistance = 0
	doorPushUp(door, 1)
	task.wait(5)
	doorPushUp(door, -1)
	clickDetector.MaxActivationDistance = distance

end)

Partie 12 : Crée un menu au départ du jeu

Objectif : Créez un menu pour le lancement du jeu

Instructions :

  1. Créer un menu de lancement du jeu : Afficher un bouton PLAY.
  2. Créer un localScript de démarrage : Lancer le jeu par le bouton play.

Créez un menu de démarrage du jeu :

Crée un localScript pour afficher le bouton PLAY puis lancer le jeu :

-- Caméra fixée sur le joueur
local camera = workspace.CurrentCamera
local playButton = script.Parent

camera.CameraType = Enum.CameraType.Fixed

-- Caméra floue autour du joueur
local BLUR = 8
local Lighting = game:GetService("Lighting")
blurEffect = Instance.new("BlurEffect")
blurEffect.Parent = Lighting
blurEffect.Size = BLUR

-- Joueur immobile
local player = game.Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
humanoid = character:FindFirstChild("Humanoid")
local walkSpeed = humanoid.WalkSpeed
humanoid.WalkSpeed = 0

local rotation = true

-- Play pour le lancement du jeu
playButton.MouseButton1Click:Connect(function()
	rotation = false
	humanoid.WalkSpeed = walkSpeed
	camera.CameraType = Enum.CameraType.Custom
	blurEffect.Size = 0
	playButton.Visible = false
end)

-- Effet pour la rotation du personnage
local humanidRootPart = character:FindFirstChild("HumanoidRootPart")
while rotation do
	humanidRootPart.CFrame = humanidRootPart.CFrame * CFrame.Angles(0, math.rad(1), 0)
	task.wait(0.01)
end

Partie 13 : Crée une animation glissade du joueur

Objectif : Crée une animation de glissade

Instructions :

Créer une animation : Lancer le jeu par le bouton play.

Créer un script pour lancer l’animation sur l’appuie d’une touche du clavier 

Choisis AVATAR puis constructeur de RIG

Choisis ton RIG :

ou sur une version plus récente de ROBLOX

R6 : Moins de parties mobiles, mouvements moins fluides, apparence plus simple.

R15 : Plus de parties mobiles, mouvements plus fluides et réalistes, apparence plus détaillée.

Déplace ton RIG pour créer l’animation

Ouvre l’éditeur d’animation :

Ou sur une version plus récente de ROBLOX

L’éditeur d’animation ouvre une Timelapse :

Une timelapse dans un éditeur d’animation est une technique qui permet de capturer et de montrer le processus de création d’une animation. Cela signifie que vous enregistrez votre travail à intervalles réguliers et ensuite vous compilez ces enregistrements en une vidéo qui montre l’ensemble du processus de l’animation.

Demande à créer l’animation sur l’ensemble du corps en appuyant sur le + :

Décoche Rotation et Déplacer

Modifie les positions du corps étape par étape pour animer une glissade :

Définis la priorité de l’animation :

Action2 : Utilisé pour les animations qui doivent avoir la priorité sur les animations d’inactivité et de mouvement, mais pas nécessairement sur les animations de haute priorité.

Sauvegarde l’animation et garde bien sa référence car tu vas en avoir besoin :

Copie la référence de l’animation :

Garde bien l’identifiant puis ferme la fenêtre:

Script de l’animation

Crée un localscript sous StarterPlayer dans StarterCharacterScripts :

Puis une animation :

Modifie les noms du script et de l’animation :

Tu peux maintenant coller la référence de l’animation dans AnimationId de ton animation :

Code du script pour lancer l’animation

Code ton script pour que l’animation se lance sur une touche du clavier, dans l’exemple la touche CTRL :

local UIS = game:GetService(« UserInputService »)


UIS.InputBegan:Connect(function(input, gpe)
if gpe then return end
if input.KeyCode == Enum.KeyCode.LeftControl then
print(« animation glissade »)
end
end)

Vérifie que tu as le message dans la sortie lorsque tu appuies sur CTRL

Code pour lancer l’animation dans une fonction et que tu ne puisses pas la lancer plusieurs fois :

local in_progress = false
local function ActivationGlissade()
if not in_progress then
in_progress = true
print(« animation glissade »)
task.wait(1)
in_progress = false
end
end


UIS.InputBegan:Connect(function(input, gpe)
if gpe then return end
if input.KeyCode == Enum.KeyCode.LeftControl then
ActivationGlissade()
end
end)

Code pour lancer l’animation :

local UIS = game:GetService(« UserInputService »)

local Character = script.Parent
local Humanoid = Character:WaitForChild(« Humanoid »)
local GlissadeAnimation = Humanoid:LoadAnimation(script:WaitForChild(« GlissadeAnimation »))


local in_progress = false

local function ActivationGlissade()
if not in_progress then
in_progress = true
GlissadeAnimation:Play()
task.wait(1)
in_progress = false
end
end

Ton animation se lance mais ne s’arrête plus :

local function ActivationGlissade()
if not in_progress then
in_progress = true
GlissadeAnimation:Play()

local humanoidRootPart = Character:WaitForChild(« HumanoidRootPart »)
local linearVelocity = Instance.new(« LinearVelocity »)
linearVelocity.Attachment0 = Instance.new(« Attachment », humanoidRootPart)
linearVelocity.MaxForce = 10000 — Définir la force maximale
linearVelocity.VectorVelocity = Character.HumanoidRootPart.CFrame.LookVector * 30
linearVelocity.Parent = Character.HumanoidRootPart

task.wait(1)

GlissadeAnimation:Stop()
linearVelocity:Destroy()

in_progress = false

end
end

Modifie ton code pour paramétrer le temps de l’animation et sa vitesse :


–Modifications de la fonction avec deux paramètres
local function ActivationGlissade(sliding_time, speed)

Humanoid.WalkSpeed = speed

linearVelocity.VectorVelocity = Character.HumanoidRootPart.CFrame.LookVector * speed
task.wait(sliding_time)


–Modifications de l’appel de la fonction temps de l’animation et vitesse
ActivationGlissade(0.5,10)


Partie 14 : Crée un tableau de scores

Objectif : Créé un tableau de scores

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

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)

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 = script.Parent -- 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)
        end
    end
end)

Partie 15 : Crée une boutique

Objectif : Créé une boutique avec des objets à acheter

Crée un bouton et une fenêtre pour ta boutique sous StarterGUI :

Pout ta boutique crée :

  • un bouton pour ouvrir et fermer la fenêtre de ta boutique
  • une fenêtre avec un titre
  • un localscript pour gérer l’ouverture de ta boutique

Ton script :

Modifie sous ServerScriptService le script leaderstats pour gérer un portemonnaie numérique :

Modifie ta boutique pour proposer l’achat d’une torche par l’ajout d’un TextButton:

L’objectif est de placer la torche achetée dans la boutique dans le BackPack du joueur. Le Backpack est principalement utilisé pour contenir des outils que les joueurs peuvent s’équiper et utiliser. Ces outils peuvent être des objets interactifs, des armes, ou tout autre objet qui peut être utilisé pour interagir avec le monde du jeu.

  • Le Backpack est principalement géré côté client. Chaque joueur a son propre Backpack, et les outils qu’il contient sont spécifiques à ce joueur.
  • Bien que le Backpack soit géré côté client, les outils peuvent être ajoutés ou retirés par des scripts côté serveur en utilisant des RemoteEvents pour communiquer avec le client.
  • ReplicatedStorage est souvent utilisé pour stocker des objets et des ressources qui doivent être partagés entre le serveur et les clients, ce qui en fait un endroit logique pour organiser les RemoteEvents.

Crée un RemoteEvent sur ReplicatedStorage :

Puis renomme le RemoteEvent :

Puis stocke une torche dans le ServerStorage.

ServerStorage offre un endroit organisé pour stocker les objets côté serveur, ce qui peut faciliter la gestion et la maintenance du code et des ressources du jeu.

Modifie le script du caddy pour prendre la torche :

Puis crée un script BuyShopService dans ServerScriptService pour ajouter la torche au BackPack :

Lance le jeu pour tester le résultat :

Achète la torche, on ne contrôle pas pour l’instant si tu disposes de suffisamment d’argent :

Maintenant contrôle si le joueur peut acheter la torche, modifie le script de ta boutique :

Puis pour tester, modifie la valeur de coins lorsque tu lances le jeu :

Au lieu de mettre l’objet dans BackPack, tu peux le mettre à disposition dans le Workspace :

Donne une position correcte à l’objet dans ServerStorage :

Ainsi que :


Partie 16 : Modifie l’éclairage du jeu

Objectif : Modifier l’éclairage global du jeu

Propose à ton joueur de vivre une ambiance différente en :

  • Modifiant le niveau de l’éclairage global.
  • Modifiant l’heure de la journée.

Change l’éclairage global

L’éclairage global correspond à la luminescence du soleil ou de la lune.

  • Dans la fenêtre de l’Explorateur , sélectionnez Lighting .
  • Dans la fenêtre Propriétés , modifie le paramètre Brightness :

Changer l’heure de la journée

Change l’heure de la journée pour modifier l’éclairage global de ton jeu.

  • Dans la fenêtre de l’Explorateur , sélectionnez Lighting .
  • Dans la fenêtre Propriétés , modifie le paramètre ClockTime :

Jouer avec un script sur la luminosité :

Crée un nouveau RemoteEvent BrightnessEvent:

Crée un script BrightnessService sous ServerScriptService :

Puis dans le script saisie le programme suivant :

Puis diminue la lumière dès que le joueur achète la torche :


Partie 17 : Crée un système de téléportation

Objectif :

Tu vas utiliser la téléportation pour ton jeu mais également pour tester plus rapidement des phases de ton jeu. Tu pourras mettre ainsi une téléportation pour déplacer ton joueur dans une zone à tester sans avoir à parcourir tout le jeu.

Mise en place des points de téléportation

Dans Workspace crée un nouveau model :

Que tu renommes Teleports :

Puis crée deux bocs :

Que tu glisses sous Teleports et renommes en TeleportA et Teleport B :

Modifie la couleur :

Modifie la taille :

Puis modifie ce paramètre :

Puis place dans ton jeu les deux points de téléportation, le point A près de ton joueur au lancement du jeu, puis le point B à l’endroit d’arrivée de ton joueur.

Programme ta première téléportation

Puis viens créer un nouveau script sous Teleleports :

Renomme le nouveau script en TeleportService :

Script de téléportation de A vers B :

-- Ressource sur le modèle de téléportation
local teleports = script.Parent	
-- Récupération des objets sur les plateformes
local teleportA = teleports.TeleportA
local teleportB = teleports.TeleportB	

-- Quand un joueur touche la première plateforme, 
-- il est téléporté sur la seconde
-- on vérifie qu'il s'agit bien d'un personnage
teleportA.Touched:Connect(function(hit)
	local character = hit.Parent
	local humanoid = character and character:FindFirstChild("Humanoid")
	if humanoid then
		character:PivotTo(CFrame.new(teleportB.Position))
	end
end)

Script de téléportation pour un système plus générique de plusieurs plateformes avec en paramètre la plateforme cible dans les attributs de la plateforme :

local teleportsForlder = script.Parent
local teleports = teleportsForlder:GetChildren()

-- Temps d'attente avant de téléporter de nouveau
local DEADLINE_OUTSIDE = teleportsForlder:GetAttribute("deadlineOutside") or 4

-- Recherche de la plateforme cible dans le répertoire
local function targetSearch(target)
	for _, teleport in ipairs(teleports) do
		if teleport:IsA("Part") then
			if teleport.Name == target then
				return teleport
			end
		end
	end
	return nil
end

-- Vérifie si le joueur est un vrai joueur (et non un NPC)
local Players = game:GetService("Players")
local function GetIsPlayer(hit)
	-- 1. 'hit' est la partie du corps qui a touché (ex: LeftLeg)
	-- On remonte au parent pour trouver le modèle du personnage (Character)
	local character = hit.Parent
	-- 2. On cherche l'objet Humanoid dans le modèle
	local humanoid = character and 
                         character:FindFirstChild("Humanoid")
	-- Si un Humanoid existe, c'est vivant (Joueur ou NPC)
	if not humanoid then return nil end
	if humanoid then
		-- 3. Vérification stricte : Est-ce un VRAI 
                --       joueur ?
		-- Cette fonction renvoie le joueur associé au 
                --       modèle, ou nil si c'est un NPC
		local player = 
                        Players:GetPlayerFromCharacter(character)
		if player then
			return player
		else
			-- C'est un humanoïde, mais pas un joueur 
                        -- (probablement un NPC)
			return nil			
		end
	end
end

-- Quand un joueur touche une téléportation
local function onTouchedTeleport(player, teleport)
	local player = GetIsPlayer(player)
	local target = 
                 targetSearch(teleport:GetAttribute("target")) 
	if target and player then
	    player.Character:PivotTo(CFrame.new(target.Position))
	end	
end

-- Génération de toutes les plateformes de téléportation
for _, teleport in ipairs(teleports) do
	if teleport:IsA("Part") then
		teleport.Touched:Connect(function(otherPart)
			onTouchedTeleport(otherPart, teleport)
		end)
	end
end

Sur le model Teleports crée la propriété deadlineOutside temps en seconde, cette propriété est utilisée pour indiquer le temps pour que le joueur puisse sortir du point de téléportation avant une nouvelle téléportation :

Puis pour chaque point de téléportation, crée une nouvelle propriété target pour indiquer le point de téléportation de destination :

Lance ton jeu et essaye la téléportation


Partie 18 : Courir plus vite

Crée un bouton pour courir plus vite dans ton jeu Roblox !

Objectif : Dans ce tutoriel, tu vas apprendre à ajouter un bouton spécial dans ton jeu Roblox. Quand le joueur cliquera dessus, son personnage courra plus vite ! C’est une fonctionnalité simple mais super utile pour rendre ton jeu plus dynamique et amusant.

Ce que tu vas découvrir

  • Tu vas découvrir comment modifier les propriétés d’un personnage notamment sa vitesse.
  • Tu vas apprendre à créer une interface pour le joueur principalement un bouton à cliquer.
  • Tu vas utiliser des scripts en Lua, le langage de programmation de Roblox, un script en local, un script sur le serveur et le système de dialogue entre le local et le serveur

Comment ça marche

Le rôle du LocalScript
  • Imagine que tu es un joueur devant ton écran.
  • Quand tu cliques sur un bouton (par exemple un bouton « Courir vite »), ton ordinateur doit comprendre que tu as fait cette action.
  • C’est le travail du LocalScript (côté client, c’est-à-dire ton PC).
  • Le LocalScript dit : « Hé serveur, le joueur a cliqué sur ce bouton ! »

Le LocalScript s’occupe d’écouter tes actions (clics, touches, GUI).

Le rôle du Script (serveur)
  • Le serveur, c’est un peu comme le maître du jeu.
  • Il reçoit les messages envoyés par les joueurs.
  • C’est lui qui a le dernier mot : il décide si l’action est acceptée ou non (pour éviter les tricheurs par exemple).
  • Le Script (serveur) dit : « J’ai bien reçu le clic du joueur. Maintenant je vais changer sa vitesse à 30 ! »

Le Script côté serveur s’occupe de changer le monde du jeu pour tout le monde.

Comment ils parlent entre eux ?

Ils utilisent un téléphone spécial appelé RemoteEvent.

  • Le LocalScript appelle FireServer() → pour envoyer un message au serveur.
  • Le Script serveur écoute avec OnServerEvent → pour réagir au message.

Crée un remoteEvent sous ReplicatedStorage :

Renomme ton RemoteEvent :

Maintenant crée un bouton avec un localscript :

local btn = script.Parent
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remote = ReplicatedStorage:WaitForChild("RunMoreEvent")

btn.Text = "Plus vite"

btn.MouseButton1Click:Connect(function()
	remote:FireServer(30)
end)

Crée un script sur le serveur pour traiter la modification de la vitesse du joueur :

Renomme ton script :

Puis saisie le code suivant :

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remote = ReplicatedStorage:WaitForChild("RunMoreEvent")

remote.OnServerEvent:Connect(function(player, value)
	local humanoid = player.character:WaitForChild("Humanoid")
	humanoid.WalkSpeed = value -- vitesse modifiée
end)

Tu peux améliorer ton script local pour revenir à une vitesse normale :

local btn = script.Parent
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remote = ReplicatedStorage:WaitForChild("RunMoreEvent")

local runMore = false
btn.Text = "Plus vite"

btn.MouseButton1Click:Connect(function()

	if runMore then
		runMore = false
		btn.Text = "Plus vite"
		remote:FireServer(16)
	else
		runMore = true
		btn.Text = "Normal"
		remote:FireServer(30)
	end

end)

Un exemple de code pour connaître la vitesse de chaque joueur lorsque celui-ci se connecte :

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local remote = ReplicatedStorage:WaitForChild("RunMoreEvent")

remote.OnServerEvent:Connect(function(player, value)
	local humanoid = player.character:WaitForChild("Humanoid")
	humanoid.WalkSpeed = value -- vitesse modifiée
end)

-- Vérification de la vitesse de départ de chaque joueur lorsqu'il se connecte
local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
	print(player.Name .. " vient de rejoindre la partie !")
	local character = player.Character or player.CharacterAdded:Wait()

	if character then
		local humanoid = character:WaitForChild("Humanoid")
		print(player.Name .. " est prêt avec un Humanoid !")
		if humanoid then
			print(player.Name .. " : " .. humanoid.WalkSpeed)
		end
	end
end)

Partie 19 : Contrôle de la vitesse du player avec les touches du clavier W et X

Crée un localScript sous StarterCharacterScripts

  • Roblox utilise les positions physiques des touches, pas les caractères.
  • Pour un clavier AZERTY, utilise le KeyCode correspondant à la position QWERTY de la touche.
  • A = Enum.KeyCode.Q
  • Q = Enum.KeyCode.A
  • W = Enum.KeyCode.Z
  • Z = Enum.KeyCode.W
local UserInputService = game:GetService("UserInputService")
local Players = game:GetService("Players")

local player = Players.LocalPlayer
local character = player.Character or player.CharacterAdded:Wait()
local humanoid = character:FindFirstChildOfClass("Humanoid")

-- Fonction pour augmenter la hauteur du saut
local function onKeyPress(input, gameProcessed)

	if input.KeyCode == Enum.KeyCode.X and not gameProcessed then
		print("appuiX", humanoid.WalkSpeed)
		if humanoid then
			humanoid.WalkSpeed += 10
		end
	end
	print(input.KeyCode, Enum.KeyCode.W)
	if input.KeyCode == Enum.KeyCode.Z and not gameProcessed then
		print("appui Z", humanoid.WalkSpeed)
		if humanoid then
			humanoid.WalkSpeed -= 10
		end
	end
end

-- Connecte l'événement
UserInputService.InputBegan:Connect(onKeyPress)

Partie 20 : Ouvrir un coffre

Dessine un coffre en deux parties, une base et un couvercle à ouvrir :

L’attribut alt de cette image est vide, son nom de fichier est image-155.png.
L’attribut alt de cette image est vide, son nom de fichier est image-156.png.

Déplace le pivot du part du couvercle vers l’arrière :

L’attribut alt de cette image est vide, son nom de fichier est image-157.png.

Le couvercle du coffre pivotera sur ce pivot pour ouvrir le coffre.

Crée un ProximityPrompt sur le couvercle :

L’attribut alt de cette image est vide, son nom de fichier est image-158.png.

Tu peux décaler le ProximityPrompt sur la droite ou la gauche avec un Attachment.

Tu peux également attacher avec un Attachment une poignée sur le couvercle du coffre. Avec un Attachment la poignée suivra le mouvement en rotation du couvercle.

L’attribut alt de cette image est vide, son nom de fichier est image-159.png.

Petite astuce si tu as besoin de coloriser la base du coffre, donc le résultat de l’union de deux part :

Script pour intercepter l’appui sur le proximityPrompt et pour ouvrir ou fermer le coffre :

local cover = script.Parent.Cover
local proxi = cover.Attachment.ProximityPrompt
local open = false

-- Fonction d'affichage du texte en 
-- fonction de l'état de la porte
local function displayActionText(open)
	return open and "Fermer" or "Ouvrir"
end

-- Fonction de rotation de la porte
local function boxOpening(door, push, rotation)
	if push ~= 0 then
		for i = 1, (rotation//math.abs(push)) do
			door:PivotTo(door:GetPivot() * CFrame.Angles(math.rad(push), 0, 0))
			wait(0.01)
		end
	end
end
-- Activation du prompt
proxi.Triggered:Connect(function()
	-- ouverture / fermeture du coffre
	proxi.Enabled = false
	boxOpening(cover, open and 1 or -1, 90)
	open = not open
	proxi.ActionText= displayActionText(open)
	proxi.Enabled = true
end)
	
proxi.ActionText= displayActionText(open)

Si tu rencontres des problèmes, vérifie que la base de ton coffre a bien cette propriété :

Change éventuellement le sens de l’ouverture :

boxOpening(cover, open and -1 or 1, 90)

Partie 20-01 : Attraper un objet

L’objectif est de récupérer dans le coffre une torche lumineuse, utile pour progresser dans les zones sombres.

Dessine la torche lumineuse, tu auras besoin d’un objet Tool, un part renommé Handle pour être saisie dans la main du joueur, et un objet SpotLight de lumière.

A partir du + à droite de Workspace demande la création d’un Tool :

Renomme cet objet Torche

Puis sous torche demande la création d’un part, renomme le Handle puis modifie les propriétés suivantes :

Puis avec le + à droite de Handle demande la création d’un SpotLight :

Modifie les propriétés de SpotLight :

Positionne la torche dans le coffre :

local cover = script.Parent.Cover
local proxi = script.Parent.Base.Attachment.ProximityPrompt
local open = false

-- Récupération de la torche et de la lumière
local torche = workspace.Torche
local light = torche.Handle.SpotLight

-- Fonction d'affichage du texte en 
-- fonction de l'état de la porte
local function displayActionText(open)
	return open and "Fermer" or "Ouvrir"
end

-- Fonction de rotation de la porte
local function boxOpening(door, push, rotation)
	if push ~= 0 then
		for i = 1, (rotation//math.abs(push)) do
			door:PivotTo(door:GetPivot() *   
                             CFrame.Angles(math.rad(push), 0, 0))
			wait(0.01)
		end
	end
end

-- Activation du proxi
proxi.Triggered:Connect(function(player)
	
	-- Si joueur a activé le proxi
	local character = player.Character
	local humanoid = character:FindFirstChild("Humanoid")
	if not humanoid then return end
	
	-- ouverture / fermeture du coffre
	proxi.Enabled = false
	boxOpening(cover, open and 1 or -1, 90)
	open = not open
	proxi.ActionText= displayActionText(open)
	proxi.Enabled = true
	
	-- vérification si le joueur a un sac à dos
	if not player:FindFirstChild("Backpack") then return end
	
	-- place la torche dans l'inventaire du joueur (Backpack)
	if torche.Parent ~= player.Backpack then
		torche.Parent = player.Backpack
	end
end)

-- active la lumière de la torche

torche.Equipped:Connect(function()
	-- Le joueur est équipé de la torche
	light.Enabled = true
end)

torche.Unequipped:Connect(function()
	-- Le joueur n'est plus équipé de la torche
	light.Enabled = false
end)

-- désactivation de la lumière de la torche au démarrage
light.Enabled = false
proxi.ActionText= displayActionText(open)

Torche dans l’inventaire du joueur :

Torche dans la main du joueur :

Evénements quand l’objet arrive dans la Backpack ou sur le joueur :

local Players = game:GetService("Players")
Players.PlayerAdded:Connect(function(player)
	-- Quand le personnage spawn
	player.CharacterAdded:Connect(function(character)
		local backpack = player:WaitForChild("Backpack")
		-- Détecter quand un item arrive dans le Backpack
		backpack.ChildAdded:Connect(function(item)
			if item:IsA("Tool") then
				print("Tool ajouté au Backpack : " .. item.Name)
			end
		end)
		character.ChildAdded:Connect(function(item)
			if item:IsA("Tool") then
				print("Tool ajouté au personnage :", item.Name)
			end
		end)
	end)
end)

Partie 21 : Allumer une lumière

Créer une pièce sombre avec un plafonnier et un interrupteur cliquable.
Quand on clique dessus, la lumière s’allume ou s’éteint.

Préparer les objets dans Roblox Studio

  1. Crée une pièce :
    • Insère un cube (Part) → redimensionne-le pour faire une petite pièce.
    • Ferme les murs, le sol et le plafond
    • Choisis des couleurs sombres.
  2. Ajoute le plafonnier :
    • Ajoute un petit Part sous le plafond, au centre.
    • Nomme-le « LightPoint ».
  3. Ajoute la lumière :
    • Sélectionne le LightPoint.
    • Dans le menu +, ajoute un PointLight.
    • Mets Enabled = false pour que la lumière soit éteinte au départ.
  4. Ajoute un interrupteur :
    • Crée un petit cube sur un mur → nomme-le LightSwitch.
    • Ajoute-lui un ClickDetector (c’est ce qui permet de cliquer dessus).
  5. Mets l’ensemble sous un Model LightingSystem

Puis ajouter le script Lua

  1. Clique sur ton model LightingSystem.
  2. Ajoute un Script (pas LocalScript).
  3. Colle ce code :
-- Récupération du système électrique
local lightingSystem = script.Parent
-- Récupération du point lumineux
local lightPoint = lightingSystem.LightPoint
-- Récupération de l'interrupteur
local lightSwitch = lightingSystem.LightSwitch



lightSwitch.ClickDetector.MouseClick:Connect(function()
	-- Inverse l'état de la lumière
	lightPoint.PointLight.Enabled = 
		not lightPoint.PointLight.Enabled

	if lightPoint.PointLight.Enabled then
		-- Allume la lumière
		lightPoint.PointLight.Brightness = 10
		lightPoint.Color = Color3.new(255, 255, 127)
	else
		-- Éteint la lumière
		lightPoint.PointLight.Brightness = 0
		lightPoint.Color = Color3.new(0, 0, 0)
	end
end)

-- Initialisation : la lumière est éteinte par défaut
lightPoint.PointLight.Enabled = false
lightPoint.PointLight.Brightness = 0
lightPoint.Color = Color3.new(0, 0, 0)

Généralisation du code si plusieurs interrupteurs ou plusieurs points de lumières sur le même système :

-- Récupération du système électrique
local lightingSystem = script.Parent:GetChildren()

local function toggleLight()
	print("click pour allumer")
	
	for _, part in pairs(lightingSystem) do

		for _, children in pairs(part:GetChildren()) do

			if (children.ClassName == "PointLight") then
				-- Inverse l'état de la lumière
				part.PointLight.Enabled = 
					not part.PointLight.Enabled

				if part.PointLight.Enabled then
					-- Allume la lumière
					print("allume")
					part.PointLight.Brightness = 10
					part.Color = Color3.new(255, 255, 127)
				else
					print("eteint")
					-- Éteint la lumière
					part.PointLight.Brightness = 0
					part.Color = Color3.new(0, 0, 0)
				end
			end
		end
	end
end

for _, part in pairs(lightingSystem) do

	for _, children in pairs(part:GetChildren()) do

		if (children.ClassName == "PointLight") then
			-- Initialisation : la lumière est éteinte par défaut
			part.PointLight.Enabled = false
			part.PointLight.Brightness = 0
			part.Color = Color3.new(0, 0, 0)
		end
		
		if (children.ClassName == "ClickDetector") then
				part.ClickDetector.MouseClick:Connect(toggleLight)
		end
	end
end

Partie 22 : Plaque de régénération du joueur

Crée un part pour représenter ta plaque de regénération

  • Dans le menu “Model”, ajouter une Part → renommer-la RegenPlate.
  • Mettre une couleur verte pour signifier la “santé”.

Introduction au script

  • Sélectionner la plaque → cliquer sur +Script.
  • Supprimer le code par défaut (print("Hello world!")).

Génère le code pour quand le joueur touche la plaque :
👉 il retrouve toute sa santé.

-- On repère la plaque de régénération
local regenPlate  = script.Parent

-- On détecte lorsque le joueur touche la plaque
regenPlate.Touched:Connect(function(hit)
	local character = hit.Parent
	-- Vérifie si l’objet touché appartient à un joueur
	local humanoid = character:FindFirstChild("Humanoid")
	-- Si un joueur est détecté
	if humanoid then
		-- Régénération de sa santé
		humanoid.Health = humanoid.MaxHealth
	end
end)

💡 Ajouter un effet lumineux pendant la régénération :

-- Étape 1 : On repère la plaque
local regenPlate  = script.Parent
-- Couleur régénératrice
local REGENCOLOR = BrickColor.new("White")
-- Temps de régénération
local REGENTTIME = 3

-- Étape 2 : On crée une fonction qui s'exécute quand le joueur touche la plaque
regenPlate.Touched:Connect(function(hit)
	local character = hit.Parent
	-- Vérifie si l’objet touché appartient à un joueur
	local humanoid = character:FindFirstChild("Humanoid")
	-- Si un joueur est détecté
	if humanoid then
		-- Si le joueur n'a pas récupéré sa santé
		-- et si n'est pas en cours de régénration
		if (humanoid.Health < humanoid.MaxHealth) and
			regenPlate.BrickColor ~= REGENCOLOR then
			-- Sauvegarde la couleur de la plaque
			local currentColor = regenPlate.BrickColor
			regenPlate.BrickColor = REGENCOLOR
			task.wait(REGENTTIME)
			-- Régénération de la santé
			humanoid.Health = humanoid.MaxHealth
			regenPlate.BrickColor = currentColor
			
		end
	end
end)

Partie 23 : Enceinte sécurisée pour le joueur

Construis avec des parts un socle et un bloc évidé transparent pour identifier l’enceinte sécurisée :

  • Sélectionner SecureArea → cliquer sur +Script.
  • Supprimer le code par défaut (print("Hello world!")).
local secureArea = script.Parent

secureArea.Touched:Connect(function(hit)
	local character = hit.Parent
	local humanoid = character:FindFirstChild("Humanoid")
	
	if humanoid  and character.Name == "123CODAGE" then
		secureArea.CanCollide = false
		task.wait(0.1)
		secureArea.CanCollide = true	
	end
end)

Partie 24 : Attraper des jetons

Crée avec Modèle puis Pièce puis Cylindre ton jeton :

Dans Explorer renomme le part en Coin puis demande l’ajout d’un son de la boîte à outil :

puis et d’un script :

Puis modifie le script pour créer une boîte de collision, un effet de particule, un effet sonore puis gérer la collision du joueur avec le jeton. :

local coin = script.Parent
local sound = script.Parent.Sound
local rotating = true
local ROTATION_SPEED = 5

-- Rotation en continue de la pièce
game:GetService("RunService").Heartbeat:Connect(function()
	if rotating then
		-- rotation de la pièce
		if coin.Transparency > 0 then 
                      coin.Transparency = 0 
                end
		coin.CFrame = coin.CFrame * 
                   CFrame.Angles(0, 0, math.rad(ROTATION_SPEED))
	end
	if not rotating then
		-- la pièce devient invisible petit à petit
		coin.Transparency += 0.01
	end
end)

-- Création d'une box de collision autour de la pièce
local hitbox = Instance.new("Part")
hitbox.Parent = coin
hitbox.Name = "Hitbox"
hitbox.Position = coin.Position
hitbox.Size = Vector3.new(2, 4, 2)
hitbox.Transparency = 1
hitbox.CanCollide = false
hitbox.Anchored = true

-- Création d'un ParticleEmitter pour l'effet de particule
local particule = Instance.new("ParticleEmitter")
particule.Parent = coin
particule.EmissionDirection = Enum.NormalId.Back
particule.Enabled = false

-- Interception de la collision avec la box de collision
hitbox.Touched:Connect(function(otherPart)
	-- controle de la collision avec le joueur
	local player = 
                      game:GetService("Players"):
                      GetPlayerFromCharacter(otherPart.Parent)
	if not player then return end	
	local humanoid = otherPart.Parent and 
                      otherPart.Parent:FindFirstChild("Humanoid")
	if not humanoid then return end
	if not rotating then return end
	-- arrêt de la rotation lancement particule et effet sonore
	rotating = false
	particule.Enabled = true

	local success, err = pcall(function()
		sound:Play()
	end)
	if not success then
		warn("Erreur lors de la lecture du son :", err)
	end

	task.wait(1.2)
        particule.Enabled = false	
        coin:Destroy()
		
end)

Rajoute un tableau de score. Si sous ServerScriptService tu n’as pas le script leaderstats alors crée le script avec la programmation suivante :

local players = game:GetService("Players")
players.PlayerAdded:Connect(function(player)

	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	
	local coins = Instance.new("IntValue")
	coins.Name = "Coins"
	coins.Parent = leaderstats
	coins.Value = 0
end)

Tu peux rajouter le décompte de jetons attrapés dans ton script :

-- ajout d'un point au score du joueur
player:WaitForChild("leaderstats").Coins.Value += 1

Modifie ton script pour générer un nouveau jeton au lieu de le détruire, remplace coin:Destroy() par ce code :

coin:Destroy()
-- déplacement aléatoire de la pièce un peu plus loin sur l'axe x en fonction de la position en rotation
coin.CFrame = coin.CFrame * 
		CFrame.new(	math.random(10,80), 0, 0)
-- déplacement aléatoire en hauteur de la pièce
coin.Position = Vector3.new(coin.Position.X, 
                            math.random(2, 15),
                            coin.position.Z)
hitbox.Position = coin.Position

rotating = true	

Système pour gérer en ensemble d’objets à attraper associés à une valeur

Crée la structure suivante :

Saisie le code suivant

local coins = script.Parent:GetChildren()
local sound = script.Parent.Sound
local ROTATION_SPEED = 5
local MAX_GAIN = 10

-- Rotation en continue de la pièce
game:GetService("RunService").Heartbeat:Connect(function()
	for _, coin in coins do
		if coin and coin:IsA("Part") then

			if coin.CanCollide then
				-- rotation de la pièce
				if coin.Transparency > 0 then 
					coin.Transparency = 0 
				end
				coin.CFrame = coin.CFrame * 
					CFrame.Angles(0, 
							math.rad(ROTATION_SPEED), 
							0)
			else
				-- la pièce devient invisible petit à petit
				coin.Transparency += 0.01
			end
		end
	end
	
end)


-- On écoute l'événement Touched de chaque part
for _, coin in coins do
	if coin and coin:IsA("Part") then
		coin.Anchored = true
		-- Création d'une box de collision autour de la pièce
		local hitbox = Instance.new("Part")
		hitbox.Parent = coin
		hitbox.Name = "Hitbox"
		hitbox.Position = coin.Position
		hitbox.Size = Vector3.new(2, 4, 2)
		hitbox.Transparency = 1
		hitbox.CanCollide = false
		hitbox.Anchored = true

		local particule = Instance.new("ParticleEmitter")
		particule.Parent = coin
		particule.EmissionDirection = Enum.NormalId.Back
		particule.Enabled = false
		
		-- Créer le conteneur (BillboardGui)
		local billboard = Instance.new("BillboardGui")
		billboard.Name = "CoinLabel"
		billboard.Adornee = coin 
		-- Taille en pixels (Largeur, Hauteur)
		billboard.Size = UDim2.new(0, 20, 0, 10) 
		-- Le texte flotte 2 studs au-dessus
		billboard.StudsOffset = Vector3.new(0, 1.5, 0)
		-- Visible même de loin ou derrière un mur
		billboard.AlwaysOnTop = false 
		-- Créer le texte (TextLabel)
		local label = Instance.new("TextLabel")
		label.Parent = billboard
		-- Prend toute la place du Billboard
		label.Size = UDim2.new(1, 0, 1, 0)
		-- Fond transparent
		label.BackgroundTransparency = 1 
		-- Valeur randomisée de la valeur du coin
		label.Text = tostring(math.random(1, MAX_GAIN)) 
		-- Jaune
		label.TextColor3 = Color3.fromRGB(255, 255, 0)
		-- Ajoute un contour noir pour la lisibilité
		label.TextStrokeTransparency = 0
		-- Le texte s'adapte à la taille
		label.TextScaled = true 
		-- Mettre le tout dans la part
		billboard.Parent = coin	
		
		-- Interception de la collision avec la box de collision
		hitbox.Touched:Connect(function(otherPart)
			-- controle de la collision avec le joueur
			local player = 
				game:GetService("Players"):
				GetPlayerFromCharacter(otherPart.Parent)
			if not player then return end	
			local humanoid = otherPart.Parent and 
				otherPart.Parent:FindFirstChild("Humanoid")
			if not humanoid then return end
			if not coin.CanCollide then return end
			-- arrêt de la rotation lancement particule et effet sonore
			particule.Enabled = true
			coin.CanCollide = false

			local success, err = pcall(function()
				sound:Play()
			end)
			if not success then
				warn("Erreur lors de la lecture du son :", err)
			end

			task.wait(1.2)
			particule:Destroy()	
			
			local gain = tonumber(coin.CoinLabel.TextLabel.Text)
			player:WaitForChild("leaderstats").Coins.Value += gain

			coin:Destroy()
			

		end)

	end
end
  • coins = liste de toutes les pièces dans le dossier où se trouve le script.
  • sound = son qui sera joué quand on ramasse une pièce.
  • ROTATION_SPEED = vitesse de rotation.
  • MAX_GAIN = valeur maximum qu’une pièce peut donner.

La fonction Heartbeat est une fonction ROBLOX qui se répète lors de l’actualisation des images, soit environ 60 fois par seconde.
Si la pièce est ramassable (CanCollide = true), elle tourne.
Si elle ne doit plus être ramassée (après collision), elle devient de plus en plus transparente pour disparaître

Au lancement du script, on prépare chaque pièce avec une boite de collition (hitbox), particules et un texte flottant avec la valeur de la pièce.

  • un effet de particules qui se jouera quand le joueur récupère la pièce.
  • une valeur affichée aléatoire entre 1 et MAX_GAIN.


Partie 25 : Grandir le joueur

Crée un part pour faire grandir ton joueur :

Ajoute ce script à un part, dès que le joueur touche le part il grandit :

local grandir = script.Parent

grandir.Touched:Connect(function(player)
	local character = player.Parent
	local humanoid = character and
                       character:FindFirstChild("Humanoid")
	if humanoid then
		humanoid.BodyHeightScale.Value = 2
		humanoid.BodyWidthScale.Value = 1
		humanoid.BodyDepthScale.Value = 1
		humanoid.HeadScale.Value = 2
	end
end)

Partie 26 : Jouer First Person

Créer le LocalScript FirstPersonScript :

  • Dans l’explorateur (Explorer), faites un clic droit sur StarterPlayer.
  • Allez dans StarterPlayerScripts.
  • Ajoutez un LocalScript (il est important que ce soit un script local, car la caméra est gérée par le client).
  • Collez le code ci-dessus dedans.
local Players = game:GetService("Players")
local player = Players.LocalPlayer
-- Fonction pour activer la première personne
local function enableFirstPerson()
	player.CameraMode = Enum.CameraMode.LockFirstPerson
end
-- L'appliquer immédiatement
enableFirstPerson()
-- S'assurer que cela reste actif si le joueur réapparaît (respawn)
player.CharacterAdded:Connect(function(character)
	enableFirstPerson()
end)

Méthode alternative (Sans code) :

Vous pouvez aussi le faire sans écrire de script, directement dans les propriétés :

  1. Cliquez sur StarterPlayer dans l’explorateur.
  2. Dans la fenêtre Properties (Propriétés), cherchez CameraMode.
  3. Changez la valeur de Classic à LockFirstPerson.

Cette méthode sans code est souvent plus simple si vous voulez que le jeu soit toujours en première personne. Le script est utile si vous voulez changer la vue dynamiquement pendant le jeu (par exemple, quand le joueur entre dans une zone spécifique ou équipe une arme).


Partie 27 : Afficher des messages informatifs

Crée cette structure dans ton workspace :

Le message s’affichera à la position du Part, sur ce dernier crée les attributs suivants :

  • Height et Width pour la taille du message
  • MaxDistance : distance à laquelle le message s’affiche pour le joueur
  • Text : message à afficher

Saisie le code suivant dans le script :

local informations = script.Parent:GetChildren()
local sound = script.Parent.Sound

-- On écoute l'événement Touched de chaque part
for _, information in informations do
	if information and information:IsA("Part") then
		information.Anchored = true
		information.CanCollide = false
		information.Transparency = 1
		local maxDistance = information:GetAttribute("MaxDistance") or 25
		local text = information:GetAttribute("Text") or ""
		local maxDistance = information:GetAttribute("MaxDistance") or 25
		local height = information:GetAttribute("Height") or "100"
		local width = information:GetAttribute("Width") or "200"
		-- Créer le conteneur (BillboardGui)
		local billboard = Instance.new("BillboardGui")
		billboard.Name = "CoinLabel"
		billboard.Adornee = information 
		-- Taille en pixels (Largeur, Hauteur)
		billboard.Size = UDim2.new(0, width, 0, height) 
		-- Le texte au centre
		billboard.StudsOffset = Vector3.new(0, 0, 0)
		-- Visible même de loin ou derrière un mur
		billboard.AlwaysOnTop = false 
		billboard.MaxDistance = 25
		-- Créer le texte (TextLabel)
		local label = Instance.new("TextLabel")
		label.Parent = billboard
		-- Prend toute la place du Billboard
		label.Size = UDim2.new(1, 0, 1, 0)
		-- Fond transparent
		label.BackgroundTransparency = 1 
		-- Valeur randomisée de la valeur du coin
		label.Text = text 
		-- Jaune
		label.TextColor3 = Color3.fromRGB(255, 255, 0)
		-- Ajoute un contour noir pour la lisibilité
		label.TextStrokeTransparency = 0
		-- Le texte s'adapte à la taille
		label.TextScaled = true 
		-- Mettre le tout dans la part
		billboard.Parent = information	

		-- Interception de la collision avec la box de collision
		information.Touched:Connect(function(otherPart)
			-- controle de la collision avec le joueur
			local player = 
				game:GetService("Players"):
				GetPlayerFromCharacter(otherPart.Parent)
			if not player then return end	
			local humanoid = otherPart.Parent and 
				otherPart.Parent:FindFirstChild("Humanoid")
			if not humanoid then return end

			local success, err = pcall(function()
				sound:Play()
			end)
			if not success then
				warn("Erreur lors de la lecture du son :", err)
			end
			
		end)
		
		information.Touched:Connect(function(otherPart)
			-- controle de la collision avec le joueur
			information:Destroy()
		end)
	end
end


Partie 28 : Coloriser des plateformes

Coloriser une plateforme en la touchant :

local part = script.Parent

part.Touched:Connect(function(hit)
	part.BrickColor = BrickColor.Yellow()
end)

Multi couleurs aléatoires :

local part = script.Parent

part.Touched:Connect(function(hit)
	part.BrickColor = BrickColor.random()
end)

Un code couleur RGB :

local part = script.Parent

part.Touched:Connect(function(hit)
	part.BrickColor = BrickColor.new(255,0,0)
end)

Une couleur personnalisée :

local part = script.Parent

part.Touched:Connect(function(hit)
	part.Color = Color3.new(204,0,0)
end)

Choix d’un matériau :

local part = script.Parent

part.Touched:Connect(function(hit)
	part.Color = Color3.new(80, 80, 0)
	part.Material = Enum.Material.Neon
end)

Comprendre les variables et les fonctions

Lance projet Baseplate :

Crée un LocalScript sous StarterPlayer puis StarterPlayerScripts:

Lance le projet :

Choisis Sortie dans Fenêtre du menu :

Hello world ! est affiché dans la fenêtre Sortie :

Les variables

Arrête le code et saisie ce code dans ton localScript :

print("Hello world!")
local Players = game:GetService("Players")
local name = Players.LocalPlayer.Name

print("Le joueur est :", name)

Si tu relances ton jeu, tu obtiens dans Sortie le résultat suivant :

Tu viens d’utiliser une variable name pour stocker le nom du joueur pour l’afficher dans la sortie :

Pour déclarer une variable : local <nom de la variable>

Une variable est comme une boîte dans laquelle tu peux stocker une information (comme un nombre, un texte, etc.). Par exemple, la variable name, le nom du joueur et tu peux créer une variable score pour contenir le nombre de points d’un joueur :

local score = 0  -- Le joueur commence avec 0 point.

Affiche le score du joueur :

print("Hello world!")
local Players = game:GetService("Players")
local name = Players.LocalPlayer.Name

print("Le joueur est :", name)

local score = 0
print("Le joueur est :", name, "avec le score["..score.."]" )

Pourquoi utiliser une variable pour le score ?

a) Garder une trace du score

Sans variable, tu devrais te souvenir du score à chaque fois. Avec une variable, ton jeu mémorise le score pour toi !

b) Facile à modifier

Si tu veux modifier, ajouter des points ou enlever des points, tu peux facilement modifier la variable score :

score = 5
score = score + 1

Change la valeur de variable score :

print("Hello world!")
local Players = game:GetService("Players")
local name = Players.LocalPlayer.Name

print("Le joueur est :", name)

local score = 0
print("Le joueur est :", name, "avec le score["..score.."]" )

score = 5
print("Le joueur est :", name, "avec le score["..score.."]" )

Puis ajoute dans score :

score = score + 1
print("Le joueur est :", name, "avec le score["..score.."]" )

Ou :

score += 1
print("Le joueur est :", name, "avec le score["..score.."]" )

Tu dois obtenir ce résultat :

Tu dois avoir le code suivant dans ton localScript :

print("Hello world!")
local Players = game:GetService("Players")
local name = Players.LocalPlayer.Name

print("Le joueur est :", name)

local score = 0
print("Le joueur est :", name, "avec le score["..score.."]" )

score = 5
print("Le joueur est :", name, "avec le score["..score.."]" )

score = score + 1
print("Le joueur est :", name, "avec le score["..score.."]" )

score += 1
print("Le joueur est :", name, "avec le score["..score.."]" )

Les fonctions

Imaginons que tu es en train de créer un jeu sur Roblox et que tu veux afficher un message personnalisé pour chaque joueur pour l’informer de son score.

Voici pourquoi utiliser une function comme affichageDuScore est une super idée, même si elle semble simple !:

print("Hello world!")
local Players = game:GetService("Players")
local name = Players.LocalPlayer.Name

local function affichageDuScore(name, score)
	print("Le joueur est :", name, 
              "avec le score["..score.."]" )	
end

print("Le joueur est :", name)

local score = 0
affichageDuScore(name, score)

score = 5
affichageDuScore(name, score)

score = score + 1
affichageDuScore(name, score)

score += 1
affichageDuScore(name, score)

Qu’est-ce que la function affichageDuScore?

C’est une petite « machine » qui prend deux informations :

  • Le nom du joueur.
  • Son score.
local function affichageDuScore(name, score)
	print("Le joueur est :", name, 
			"avec le score["..score.."]" )	
end

Et elle affiche automatiquement le bon message. Par exemple :

11:39:01.641 Le joueur est : 123CODAGE avec le score[7] – Client – LocalScript:10

Pourquoi utiliser une fonction pour ça ?

Tout est au même endroit

Sans la fonction, tu devrais écrire le même code plusieurs fois dans ton jeu.

Avec la fonction, tu écris une seule fois la logique et tu l’utilises partout avec un simple :

affichageDuScore(name, score)

Et un autre exemple de forme de function :

print("Hello world!")
local Players = game:GetService("Players")
local name = Players.LocalPlayer.Name

local function affichageDuScore(name, score)
	print("Le joueur est :", name, 
			"avec le score["..score.."]" )	
end

local function scorePlus(score)
	return score + 1
end

print("Le joueur est :", name)

local score = 0
affichageDuScore(name, score)

score = 5
affichageDuScore(name, score)

score = scorePlus(score)
affichageDuScore(name, score)

score = scorePlus(score)
affichageDuScore(name, score)

Tu peux tester une variable, par exemple :

if score > 7 then
	print(name.." tu es le best")
else
	print(name.." tu peux mieux faire")
end

Qu’est-ce que la function isBest ?

Tu veux savoir si un joueur est un « champion » (par exemple, s’il a un score d’au moins 7). Voici pourquoi utiliser une function comme isBest est une super idée !

C’est une petite « boîte magique » qui répond à une question : « Est-ce que ce score fait de ce joueur un champion ? » Elle prend un score en entrée et retourne true (oui) ou false (non).

local function isBest(score)
	return score >= 7	
end

if isBest(score) then
	print(name.." tu es le best")
else
	print(name.." tu peux mieux faire")
end

Bien sûr ! Imaginons que tu crées un jeu sur Roblox où les joueurs ont un score. Tu veux savoir si un joueur est un « champion » (par exemple, s’il a un score d’au moins 7). Voici pourquoi utiliser une fonction comme estChampion est une super idée !

Qu’est-ce que la fonction isBest ?

C’est une petite « boîte magique » qui répond à une question : « Est-ce que ce score fait de ce joueur un champion ? » Elle prend un score en entrée et retourne true (oui) ou false (non).

Pourquoi utiliser une fonction pour ça ?

Éviter de répéter le même code

Sans la fonction, tu devrais écrire score >= 7 à chaque fois que tu veux vérifier si un joueur est un champion. Avec la fonction, tu écris isBest(score) et c’est tout !

Tu peux optimiser ton code :

local function isBest(score)
	return score >= 7	
end

print(name .. (isBest(score) and
	" tu es le best" or
	" tu peux mieux faire"))

Qu’est-ce qu’une constante ?

Une constante est une variable dont la valeur ne change jamais pendant que ton programme tourne. En Lua (le langage de Roblox), on utilise souvent une convention pour montrer que c’est une constante : on écrit son nom en majuscules.

Exemple :

local POINTS_PAR_VICTOIRE = 1

Même si ajouter 1 point semble simple, utiliser une constante comme POINTS_PAR_VICTOIRE a plusieurs avantages :

a) Facile à modifier plus tard

Si demain tu veux que le joueur gagne 2 points au lieu de 1, tu n’as qu’à changer une seule ligne :

local POINTS_PAR_VICTOIRE = 2  -- Au lieu de 1

ans constante, il faudrait chercher tous les endroits où tu as écrit + 1 et les modifier un par un. Avec une constante, c’est automatique !

b) Plus clair et compréhensible

Quand tu lis ce code :

score = score + POINTS_PAR_VICTOIRE
Tu comprends tout de suite que le joueur gagne des points pour une victoire. Si tu vois juste + 1, tu ne sais pas pourquoi on ajoute 1.

Le code complet

print("Hello world!")
local Players = game:GetService("Players")
local name = Players.LocalPlayer.Name

local INCREMENT_SCORE = 1
local BEST = 7

-- Affichage du score
local function affichageDuScore(name, score)
	print("Le joueur est :", name, 
			"avec le score["..score.."]" )	
end

-- Plus sur le score
local function scorePlus(score)
	return score + INCREMENT_SCORE
end

-- Si champion
local function isBest(score)
	return score >= BEST	
end

print("Le joueur est :", name)

local score = 0
affichageDuScore(name, score)

score = 5
affichageDuScore(name, score)

score = scorePlus(score)
affichageDuScore(name, score)

score = scorePlus(score)
affichageDuScore(name, score)

print(name .. (isBest(score) and
	" tu es le best" or
	" tu peux mieux faire"))

Faire courir le joueur

Voici une démarche étape par étape pour créer un menu, ajouter un bouton et lui attacher un LocalScript dans Roblox Studio. Suis ces instructions dans l’ordre pour que tout fonctionne !

Créer un menu (ScreenGui)

Un menu dans Roblox est souvent un ScreenGui (une interface qui s’affiche à l’écran).

Étapes :

  1. Dans l’onglet Explorer (à droite), trouve StarterGui.
  2. Clique droit sur StarterGui ou le petit + → Insérer un objetScreenGui.
    • Cela crée un ScreenGui (ton menu).

Maintenant, ajoute un bouton dans ton ScreenGui.

Étapes :

  1. Dans l’Explorer, sélectionne ton ScreenGui (MenuPrincipal).
  2. Clique droit sur ScreenGui ou le petit + → Insérer un objetTextButton.
    • Un bouton apparaît dans ton menu.
  3. Personnalise le bouton :
    • Dans l’onglet Propriétés (à droite), modifie Text : Écris "Vitesse plus" (le texte sur le bouton).

Ajouter un LocalScript au bouton

Un LocalScript permet de faire réagir le bouton quand un joueur clique dessus.

Étapes :

  1. Dans l’Explorer, sélectionne ton bouton (TextButton).
  2. Clique droit sur BoutonJouerInsérer un objetLocalScript.
    • Un LocalScript apparaît dans le bouton.

Écrire le code du LocalScript pour changer la vitesse de course du joueur :

local Players = game:GetService("Players")
local btn = script.Parent

-- change la vitesse du joueur
local speed = 40 -- vitesse du joueur

btn.MouseButton1Click:Connect(function()
	print("Le joueur a cliqué sur le bouton")
	local character = Players.LocalPlayer.Character or 
		Players.LocalPlayer.CharacterAdded:Wait()
	local humanoid = character:WaitForChild("Humanoid")

	humanoid.WalkSpeed = speed
end)

Explication du code :

  • script.Parent : Fait référence au bouton (TextButton).
  • MouseButton1Click:Connect(...) : Écoute le clic de la souris sur le bouton.
  • Quand le bouton est cliqué, le code à l’intérieur de la fonction s’exécute pour changer la vitesse du joueur

Les listes

Une liste, c’est comme une boîte qui contient plusieurs objets, rangés les uns après les autres.

👉 En Lua, on appelle ça une table.
C’est un peu comme un carton à cases : chaque case contient quelque chose.

Crée un script sous le Workspace :

Pour écrire une liste {} :

local scores = {10, 20, 30, 12, 51}
print(scores)

Si tu lances le projet, tu constates ce résultat dans Sortie :

Tu peux également construire une liste de listes :

local scores = {{"Chloé",10}, 
				{"Noah",20}, 
				{"Alexandre",30}, 
				{"Kilyan",12}, 
				{"Louise",51}}
print(scores)

Tu peux supprimer un item d’une liste en précisant son rang en commençant par 1 :

local scores = {{"Chloé",10}, 
				{"Noah",20}, 
				{"Alexandre",30}, 
				{"Kilyan",12}, 
				{"Louise",51}}
table.remove(scores, 2)
print(scores)

Rajouter en fin de liste un nouveau item :

local scores = {{"Chloé",10}, 
				{"Noah",20}, 
				{"Alexandre",30}, 
				{"Kilyan",12}, 
				{"Louise",51}}
table.remove(scores, 2)
table.insert(scores, {"Esteban", 23})
print(scores)

Tu peux connaître le nombre items dans une liste :

local scores = {{"Chloé",10}, 
				{"Noah",20}, 
				{"Alexandre",30}, 
				{"Kilyan",12}, 
				{"Louise",51}}
table.remove(scores, 2)
table.insert(scores, {"Esteban", 23})
print(scores)
print(#scores)

Tu peux lire la liste dans une boucle :

local scores = {{"Chloé",10}, 
				{"Noah",20}, 
				{"Alexandre",30}, 
				{"Kilyan",12}, 
				{"Louise",51}}
table.remove(scores, 2)
table.insert(scores, {"Esteban", 23})
print(scores)
print(#scores)
for index, score in ipairs(scores) do
	print(index,"nom : "..score[1],"score : "..score[2])
end

Si tu n’as pas besoin de l’index de la table :

for _, score in ipairs(scores) do
	print("nom : "..score[1],"score : "..score[2])
end

Si tu veux connaître tous les items de ton workspace, tu peux demander à les mettre dans une liste et ainsi les manipuler :

	
local folders = workspace:GetChildren()

print(folders)

for _, folder in ipairs(folders) do
	print(folder.Name, folder.ClassName)
end

Et également un sous répertoire du workspace :

local folders = workspace:GetChildren()

print(folders)

for _, folder in ipairs(folders) do
	print(folder.Name, folder.ClassName)
	if folder.ClassName == "Part" then
		for _, subFolder in ipairs(folder:GetChildren()) do
			print("-",subFolder.Name, subFolder.ClassName)
		end
	end
end

Si tu veux généraliser pour lire tous le workspace :

local function explore(folder, indent)

	for _, obj in ipairs(folder:GetChildren()) do
		print(string.rep("-", indent), "Nom :", obj.Name, " | Type :", obj.ClassName)

		-- Si l'objet contient d'autres objets, on recommence dedans
		if #obj:GetChildren() > 0 then
			explore(obj, indent+1)
		end
	end
end

-- On commence par le Workspace
explore(workspace, 0)


Changer les propriétés d’un objet ROBLOX

Renomme le part en « MyPart »:

Lance ton jeu et visualise ton part :

Crée un script sur ton part :

local myPart = script.Parent

  • Ici, on crée une variable qui s’appelle myPart.
  • Cette variable pointe vers l’objet auquel le script est attaché (par exemple un part dans Roblox Studio).
  • Comme ça, au lieu de réécrire script.Parent tout le temps, on peut juste écrire myPart.

Changer la couleur du bloc

local myPart = script.Parent

myPart.Color = BrickColor.Blue()

myPart.Color = BrickColor.Blue()

  • On dit à Roblox : « change la couleur du bloc ».
  • myPart.Color correspond à la propriété couleur du bloc.
  • BrickColor.Blue() dit : prends la couleur bleue de Roblox.

Donc, cette ligne change la couleur du bloc en bleu.

Une autre façon de mettre une couleur :

myPart.Color = Color.new(0, 0, 255)

Qu’est-ce que RGB ?

  • R = Rouge (Red)
  • G = Vert (Green)
  • B = Bleu (Blue)
local myPart = script.Parent

myPart.BrickColor = BrickColor.new(0, 1, 0)

for red = 0, 255 do
	myPart.Color = Color3.fromRGB(red, 0, 0)
	task.wait(0.01)
end

for green = 255, 0, -1 do
	myPart.Color = Color3.fromRGB(0, green, 0)
	task.wait(0.01)
end

for blue = 0, 255 do
	myPart.Color = Color3.fromRGB(0, 0, blue)
	task.wait(0.01)
end

Ce sont les 3 couleurs de base de la lumière (comme les lampes de ton écran).
En les mélangeant, on peut obtenir toutes les autres couleurs.

local myPart = script.Parent


while true do
	
	for red = 0, 255, 50 do
		for green = 0, 255, 50 do
			for blue = 0, 255, 50 do
				myPart.Color = Color3.fromRGB(red, green, blue)
				task.wait(0.01)
				print(red, green, blue)
			end	
		end	
	end

end

Fixer le bloc

Sous la pression du player le bloc bouge ou tombe :

local myPart = script.Parent

myPart.Anchored = true

myPart.Anchored = true

  • Anchored est une propriété du bloc.
  • En anglais, ça veut dire ancré ou fixé.
  • Quand Anchored = true, le bloc ne peut plus bouger avec la gravité ou les collisions.
  • Quand Anchored = false, le bloc tombe si rien ne le soutient, et il peut être poussé.

Rendre transparent le bloc

local myPart = script.Parent

myPart.Anchored = true
myPart.Transparency = 0.5

Transparency veut dire transparence (comme du verre).

C’est une valeur qui va de 0 à 1 :

  • 0 = pas transparent du tout (opaque, on voit bien le bloc).
  • 1 = complètement transparent (invisible).
  • Entre les deux (par exemple 0.5), le bloc est semi-transparent (on le voit un peu mais on voit aussi à travers).

Traverser le bloc

local myPart = script.Parent

myPart.Anchored = true
myPart.Transparency = 0.5
myPart.CanCollide = false

En anglais, « Can Collide » = « peut entrer en collision ».

C’est une propriété booléenne (elle peut être soit true, soit false).

  • true → le bloc est solide, on peut marcher dessus, il bloque le joueur.
  • false → le bloc devient fantôme, on peut traverser comme s’il n’était pas là.

Déplacer le boc

local myPart = script.Parent

myPart.Anchored = true
myPart.Transparency = 0.5
myPart.CanCollide = false

for x = 1,200, 0.1 do
	myPart.CFrame = myPart.CFrame + Vector3.new(x, 0, 0)	
	task.wait(0.1)
end

CFrame = Coordinate Frame (en anglais).
C’est la position ET l’orientation d’un objet dans l’espace 3D.
Quand tu modifies CFrame, tu dis à Roblox :
« mets mon bloc à une nouvelle position dans le monde ».

Vector3 = un point ou un déplacement dans l’espace 3D.
Il a 3 nombres :

  • x → gauche/droite (axe horizontal).
  • y → haut/bas (axe vertical).
  • z → avant/arrière (profondeur).

👉 Exemple :

  • Vector3.new(5, 0, 0) = déplace de 5 cases à droite.
  • Vector3.new(0, 5, 0) = monte de 5 cases.
  • Vector3.new(0, 0, 5) = avance de 5 cases.
myPart.CFrame = myPart.CFrame + Vector3.new(x, 0, 0)

On dit :
« prends la position actuelle du bloc, et ajoute-lui un déplacement de x sur l’axe X (droite/gauche) ».

Tourner le bloc

Quand tu ajoutes un Vector3, tu modifies la position (où est le bloc).
Quand tu ajoutes une rotation, tu modifies l’orientation (comment il est tourné).

myPart.CFrame = CFrame.Angles(0, math.rad(90), 0)

Le bloc pivote d’un quart de tour (comme tourner une porte ouverte à angle droit).

CFrame.Angles crée une rotation.

Les trois valeurs x, y, z correspondent à des rotations en radians :

  • x → rotation autour de l’axe X (il bascule en avant/arrière).
  • y → rotation autour de l’axe Y (il tourne comme une toupie).
  • z → rotation autour de l’axe Z (il penche sur le côté).
math.rad(90)

math.rad() convertit les radians en degré

radians=degrés×(180/π)​

Faire grossir un bloc et voir sa masse grandir

Un script simple qui montre comment la masse d’un bloc change quand on le fait grossir.

local myPart = script.Parent

myPart.Color = BrickColor.Blue()

-- On affiche la masse au début
print("Masse au départ :", myPart:GetMass())

-- On agrandit le bloc petit à petit
for i = 1, 5 do
	wait(1)  -- attend 2 secondes
	myPart.Size = myPart.Size + Vector3.new(2, 2, 2)  -- grossit de 2 en largeur, hauteur et profondeur

	print("Nouvelle taille :", myPart.Size)
	print("Nouvelle masse :", myPart:GetMass())
end

Dans Roblox Studio :

  1. Clique sur ton bloc dans Explorer.
  2. Fais + et ajoute un BillboardGui.
  3. Dans ce BillboardGui, ajoute un TextLabel.

local myPart = script.Parent
local billboard = myPart:FindFirstChild("BillboardGui")

-- Positionnement de l'étiquette sur le coté droit de la part
billboard.StudsOffset = Vector3.new(4, 0, 0)

if billboard then
	-- TextLabel qui affiche la masse
	local label = billboard:FindFirstChild("TextLabel")
	-- Couleur de fond transparente pour laisser la part visible
	label.BackgroundTransparency = 1
	label.Text = ""
	if label then
		-- Fait grossir le bloc et met à jour la masse
		for i = 1, 5 do
			task.wait(1)
			myPart.Size = myPart.Size + Vector3.new(2, 2, 2)
			-- Fonction pour mettre à jour le texte avec la masse
			billboard.StudsOffset = billboard.StudsOffset + Vector3.new(2, 0, 0)
			label.Text = "Masse : " .. math.floor(myPart:GetMass())
		end
	else
		warn("TextLabel not found in BillboardGui")
	end
else
	warn("BillboardGui not found in MyPart")
end

Conclusion

En suivant ces instructions, vous serez en mesure de créer un obby complet et fonctionnel sur Roblox. Assurez-vous de respecter tous les critères et d’utiliser les indices pour vous aider à compléter chaque partie. Bonne chance et amusez-vous bien !

Catégories
ROBLOX

ROBLOX suggestions

Des suggestions pour débuter en ROBLOX LUA :
créer un commentaire dans ton code,
rechercher une ressource,
détecter un click d’une souris, déplacer un part,
pousser un objet,
synchroniser avec le moteur ROBLOX,
tester l’appartenance d’un objet à une classe,
tester si la collision vient d’un joueur,
modifier la santé du joueur,
modifier vitesse du joueur,
détecter une collision du joueur avec un objet Roblox,
détecter une fin de collision avec le joueur,
réduire la santé du joueur,
comment coder un ClickDetector,
comment coder un Prompt,
créé un système de message RemoteEvent,
ajouter dans l’inventaire,
créer un tableau de score,
comment intercepter une erreur,
rotation d’un objet,
intercepter une touche de clavier

Commentaire d’une ligne :

--print("instruction en commentaire")

Commentaire de plusieurs instructions :

--[[
print("instruction en commentaire")
print("instruction en commentaire")
--]]

Recherche d’une ressource dans un script :

-- recherche d'un objet sous la même arborescence que le script
local btOpenMenu = script.Parent.OpenButton

-- recherche d'un part sous workspace
local myPart = workspace.part

-- recherche de plusieurs part sous un folder
local myParts = workspace.Folder:GetChildren()

-- recherche des joueurs et du joueur local dans un localScript
local players = game:GetService("Players")
local player = players.LocalPlayer

-- récupération de tous les parts dans le workspace
for _, part in ipairs(myParts ) do

end

Comment détecter un click de la souris sur un bouton :

btOpenMenu.MouseButton1Click:Connect(function()

end)

Comment déplacer un objet Roblox :

myPart.Position += Vector3.new(10,0,0)

Déplacer un objet x fois :

for i = 1, 50 do
   maPart.Position += Vector3.new(5,0,0)
   wait(1)
end

Déplacer un objet Roblox tout le temps :

while true do
    maPart.Position += Vector3.new(0.05,0,0)
    wait(0.01)
end

Déplacer un objet jusqu’à une position :

while maPart.Position.X<60 do
   maPart.Position += Vector3.new(5,0,0)
   wait(0.01)
end

Pouser un objet :

part.AssemblyLinearVelocity = Vector3.new(0, 0, 100)

Synchroniser le déplacement avec le moteur de Roblox :

game:GetService("RunService").Heartbeat:Connect(function()
    maPart.Position += Vector3.new(0.05,0,0)
end)

Comment tester l’appartenance d’un objet à une classe :

if otherPart:IsA("Part") then
	print("Part : ",otherPart.Name)

Comment tester si la collision vient d’un joueur :

part.Touched:Connect(function(hit)
    -- 1. Remonte jusqu'au Model parent (le Character)
    local character = hit:FindFirstAncestorOfClass("Model")
    if not character then return end

    -- 2. Cherche le Humanoid dans le Character
    local humanoid = character:FindFirstChildOfClass("Humanoid")
    if not humanoid or humanoid.Health <= 0 then return end

    -- 3. Retrouve le Player depuis le Character
    local player = game:GetService("Players"):GetPlayerFromCharacter(character)
    if not player then return end

    print("Joueur touché :", player.Name)
end)

Comment modifier la santé du joueur :

local humanoid = otherPart.Parent and otherPart.Parent:FindFirstChild("Humanoid")
if not humanoid then return end

humanoid.Health = 0

Maximum de santé :

humanoid.MaxHealth

Comment modifier vitesse du joueur :

local humanoid = otherPart.Parent and otherPart.Parent:FindFirstChild("Humanoid")
if not humanoid then return end

humanoid.WalkSpeed = 20

Comment détecter une collision du joueur avec un objet Roblox :

maPart.Touched:Connect(function(otherPart)

    local humanoid = otherPart.Parent and otherPart.Parent:FindFirstChild("Humanoid")
    if not humanoid then return end

Comment détecter une fin de collision avec le joueur :

maPart.TouchEnded:Connect(function(otherPart)

    local humanoid = otherPart.Parent and  
                 otherPart.Parent:FindFirstChild("Humanoid")
    if not humanoid then return end

end)

Santé du joueur à 100 au départ du jeu :

print(humanoid.Health)

Réduire la santé du joueur :

humanoid.Health = humanoid.Health – 5
ou
humanoid:TakeDamage((5))

Le joueur meurt quand sa santé est à zéro :

humanoid.Health = 0

Comment coder un ClickDetector sur le part :

local clickDetector = script.Parent.ClickDetector

clickDetector.MouseClick:Connect(function()
print(« touché »)
end)

Comment coder un Prompt :

maPart.ProximityPrompt.Triggered:Connect(function(otherPart)
print(‘activé’)
end)

Créé un système de message RemoteEvent

Sous ReplicatedStorage crée un RemoteEvent

Dans un localScript :

local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")

remoteEvent:FireServer(param1, param2, ...)

Puis dans un script serveur :

local remoteEvent = ReplicatedStorage:WaitForChild("RemoteEvent")

remoteEvent .OnServerEvent:Connect(function(player, param1, param2, ...)

end)

Ajouter dans l’inventaire :

item.Parent = player.Backpack

Créer un tableau de score :

Insérer un script leaderstats sous ServerScriptService :

local players = game:GetService("Players")

players.PlayerAdded:Connect(function(player)

	local leaderstats = Instance.new("Folder")
	leaderstats.Name = "leaderstats"
	leaderstats.Parent = player
	-- Exemple de valeurs du tableau
	local coins = Instance.new("IntValue")
	coins.Name = "Coins"
	coins.Parent = leaderstats
	coins.Value = 0
end)

Puis pour modifier le score dans un script serveur :

local player =
               game:GetService("Players"):
               GetPlayerFromCharacter(otherPart.Parent)
if not player then return end	
	
player:WaitForChild("leaderstats").Coins.Value += 1

Comment intercepter une erreur par exemple sur « jouer un son » :

	local success, err = pcall(function()
		sound:Play()
	end)
	if not success then
		warn("Erreur lors de la lecture du son :", err)
	end

Rotation d’un objet :

local mypart = script.Parent

mypart.Touched:Connect(function(hit)
	mypart:PivotTo(mypart:GetPivot() *
                       CFrame.Angles(math.rad(90), 0, 0))
end)

Intercepter une touche de clavier :

Dans un LocalScript sous StarterPlayer StarterPlayerScripts

local UserInputService = game:GetService("UserInputService")

print("clavier bbb")
-- Connecte l'événement
UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if input.KeyCode ~= Enum.KeyCode.Unknown then
		print("Clavier", input.KeyCode)

		if input.KeyCode == Enum.KeyCode.X and not gameProcessed then
			print("Appui X")
		end

	end

end)