Créer un script pour afficher un tableau de score au joueur sousServerScriptService :
Renommer le script leaderstats :
Saisir le code suivant pour un affichage d’une barre de scores :
local players = game:GetService("Players")
players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
end)
Si tu lances ton jeu une barre s’affiche :
Si le score ne s’affiche pas vérifie :
Rajoute à ton script un score à afficher :
local players = game:GetService("Players")
players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local score = Instance.new("IntValue")
score.Parent = leaderstats
score.Name = "Score"
score.Value = 0
end)
Le score s’affiche si tu lances ton jeu :
Exemple d’un script pour augmenter le score si le joueur click sur un ClickDetector :
local clickDetector = script.Parent.ClickDetector
clickDetector.MouseClick:Connect(function(player)
player:WaitForChild("leaderstats").Score.Value += 10
end)
Exemple d’un script pour augmenter le score si le joueur rentre en collision avec un part :
local myPart = script.Parent
myPart.Touched:Connect(function(hit)
-- Vérifie si c'est un joueur qui a touché la part
local joueur = game:GetService("Players"):GetPlayerFromCharacter(hit.Parent)
if joueur then
-- Trouve le score du joueur dans Leaderstats
local leaderstats = joueur:FindFirstChild("leaderstats")
if leaderstats then
local score = leaderstats:FindFirstChild("Score")
if score then
-- Incrémente le score
score.Value = score.Value + 1
end
end
end
end)
Les checkpoints sont des points de sauvegarde dans un jeu. Quand un joueur touche un checkpoint, sa position est enregistrée. Si le joueur meurt ou revient dans la partie, il réapparaît au dernier checkpoint touché.
Dans ce script, les checkpoints ne sont pas ordonnés : le joueur peut les toucher dans n’importe quel ordre.
Comment parcourir les checkpoints dans un dossier avec une boucle for.
Comment stocker le dernier checkpoint pour chaque joueur.
Comment détecter quand un joueur revient dans la partie et le téléporter à son dernier checkpoint.
Préparation dans Roblox Studio
Pour tester ce script, suis ces étapes :
Créer un dossier pour les checkpoints :
Dans Workspace, crée un dossier nommé CheckpointsFolder.
Ajouter des checkpoints :
Ajoute plusieurs Part dans CheckpointsFolder.
Nomme-les comme tu veux (ex: Checkpoint1, Checkpoint2, etc.).
Place-les à différents endroits dans ton jeu.
Ajouter le script :
Crée un Script dans ServerScriptService et copie le code suivant.
Le script supprime automatiquement la Baseplate pour éviter les interférences.
Si tu veux garder un sol, ajoute une Part plate dans Workspace.
Voici le script commenté pour comprendre :
-- Récupérer les services et objets nécessaires
local Players = game:GetService("Players") -- Service pour gérer les joueurs
-- Récupérer la Baseplate et le dossier des checkpoints
local baseplate = workspace:WaitForChild("Baseplate")
local checkpointsFolder = workspace:WaitForChild("CheckpointsFolder")
-- Tableau pour stocker le dernier checkpoint de chaque joueur
-- Format : playerCheckpoints[userId] = CFrame du dernier checkpoint
local playerCheckpoints = {}
-- Supprimer la Baseplate (pour éviter les interférences)
baseplate:Destroy()
-- Fonction appelée quand un personnage est ajouté (ex: quand un joueur respawn)
local function onCharacterAdded(character, userId)
-- Récupérer le dernier checkpoint du joueur
local storedCFrame = playerCheckpoints[userId]
-- Si le joueur n'a pas de checkpoint enregistré, on ne fait rien
if not storedCFrame then
return
end
-- Attendre que le HumanoidRootPart existe (partie principale du personnage)
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
-- Ajouter un petit décalage aléatoire pour éviter que les joueurs spawnent au même endroit
local offset = Vector3.new(math.random(-1, 1), 4, math.random(-1, 1))
-- Téléporter le joueur à son dernier checkpoint + décalage
humanoidRootPart.CFrame = storedCFrame + offset
end
-- Fonction appelée quand un joueur touche un checkpoint
local function onTouched(checkpoint, hit)
-- Récupérer le personnage qui a touché le checkpoint
local character = hit.Parent
-- Vérifier si c'est bien un personnage avec un Humanoid (un joueur)
if not character or not character:FindFirstChildOfClass("Humanoid") then
return
end
-- Récupérer le joueur associé au personnage
local player = Players:GetPlayerFromCharacter(character)
if not player then
return
end
-- Récupérer l'ID unique du joueur
local userId = player.UserId
-- Connecter l'événement CharacterAdded UNE SEULE FOIS par joueur
-- Cela évite de connecter plusieurs fois le même événement
if not playerCheckpoints[userId] then
player.CharacterAdded:Connect(function(newCharacter)
onCharacterAdded(newCharacter, userId)
end)
end
-- Stocker le CFrame (position + rotation) du checkpoint pour ce joueur
playerCheckpoints[userId] = checkpoint.CFrame
end
-- Parcourir tous les checkpoints dans le dossier CheckpointsFolder
for _, checkpoint in ipairs(checkpointsFolder:GetChildren()) do
-- Vérifier si l'objet est une BasePart (ex: une Part)
if not checkpoint:IsA("BasePart") then continue end
-- Configurer le checkpoint
checkpoint.Anchored = true -- Empêcher le checkpoint de bouger
checkpoint.CanCollide = true -- Permettre les collisions
checkpoint.Transparency = 0.5 -- Rendre le checkpoint semi-transparent
checkpoint.Material = Enum.Material.Neon -- Matériau Neon pour un effet lumineux
checkpoint.BrickColor = BrickColor.new("Bright blue") -- Couleur bleue vive
-- Connecter l'événement Touched pour détecter quand un joueur touche le checkpoint
checkpoint.Touched:Connect(function(hit)
onTouched(checkpoint, hit)
end)
end
Le script supprime automatiquement la Baseplate.
1.La boucle for pour parcourir les checkpoints
for _, checkpoint in ipairs(checkpointsFolder:GetChildren()) do
if not checkpoint:IsA("BasePart") then continue end
-- Configurer le checkpoint...
end
checkpointsFolder:GetChildren() :
Récupère tous les enfants directs du dossier CheckpointsFolder.
Retourne une liste de tous les objets dans ce dossier.
ipairs(...) :
Parcourt la liste des enfants un par un.
_ est une variable temporaire (non utilisée) qui représente l’index (position dans la liste).
checkpoint est l’objet actuel dans la boucle (ex: une Part).
if not checkpoint:IsA("BasePart") then continue end :
Vérifie si checkpoint est une BasePart (ex: une Part).
Si ce n’est pas le cas (ex: un Folder, un Script), on passe à l’itération suivante avec continue.
Pourquoi utiliser GetChildren ?
On veut trouver tous les checkpoints dans le dossier CheckpointsFolder.
GetChildren est plus rapide que GetDescendants car on ne cherche que les enfants directs (pas les petits-enfants).
2. Stocker le checkpoint pour le joueur
local playerCheckpoints = {} -- Tableau pour stocker les checkpoints
-- Dans la fonction onTouched :
playerCheckpoints[userId] = checkpoint.CFrame
playerCheckpoints :
C’est un tableau associatif où :
Clé = userId (l’ID unique du joueur).
Valeur = CFrame du dernier checkpoint touché par le joueur.
checkpoint.CFrame :
Le CFrame est une propriété qui stocke la position et la rotation d’un objet.
Quand un joueur touche un checkpoint, on stocke son CFrame dans playerCheckpoints[userId].
Pourquoi utiliser userId comme clé ?
Chaque joueur a un ID unique (UserId).
Cela permet de stocker un checkpoint différent pour chaque joueur.
3. Détecter quand le joueur revient dans la partie
-- Dans la fonction onTouched :
if not playerCheckpoints[userId] then
player.CharacterAdded:Connect(function(newCharacter)
onCharacterAdded(newCharacter, userId)
end)
end
-- Fonction onCharacterAdded :
local function onCharacterAdded(character, userId)
local storedCFrame = playerCheckpoints[userId]
if not storedCFrame then return end
local humanoidRootPart = character:WaitForChild("HumanoidRootPart")
local offset = Vector3.new(math.random(-1, 1), 4, math.random(-1, 1))
humanoidRootPart.CFrame = storedCFrame + offset
end
player.CharacterAdded:Connect(...) :
Événement déclenché quand un joueur respawn (réapparaît après être mort ou avoir rejoint le jeu).
On connecte une seule fois cet événement par joueur (grâce à if not playerCheckpoints[userId]).
onCharacterAdded :
Cette fonction est appelée quand un joueur réapparaît.
Elle téléporte le joueur à son dernier checkpoint (storedCFrame).
offset : Ajoute un petit décalage aléatoire pour éviter que plusieurs joueurs spawnent au même endroit.
WaitForChild("HumanoidRootPart") :
Attend que le HumanoidRootPart (partie centrale du personnage) existe avant de le téléporter.
Cela évite les erreurs si le personnage n’est pas encore complètement chargé.
QCM : Teste ta compréhension !
Sur la boucle for et GetChildren :
Que fait checkpointsFolder:GetChildren() ?
a) Récupère tous les enfants directs du dossier CheckpointsFolder.
b) Récupère tous les descendants (enfants, petits-enfants, etc.) du dossier.
c) Supprime tous les enfants du dossier.
Pourquoi utilise-t-on if not checkpoint:IsA("BasePart") then continue end ?
a) Pour ignorer les objets qui ne sont pas des BasePart (ex: des Folder).
b) Pour supprimer les checkpoints.
c) Pour changer la couleur des checkpoints.
Que contient la variable checkpoint dans la boucle for ?
a) Un objet (ex: une Part) dans le dossier CheckpointsFolder.
b) Un nombre.
c) Un joueur.
Sur le stockage des checkpoints :
À quoi sert playerCheckpoints[userId] = checkpoint.CFrame ?
a) Stocker la position et la rotation du checkpoint pour un joueur.
b) Supprimer le checkpoint.
c) Changer la taille du checkpoint.
Pourquoi utilise-t-on userId comme clé dans playerCheckpoints ?
a) Parce que chaque joueur a un ID unique, ce qui permet de stocker un checkpoint différent pour chaque joueur.
b) Parce que c’est plus rapide.
c) Parce que c’est obligatoire.
Que fait playerCheckpoints[userId] si userId n’existe pas dans le tableau ?
a) Retourne nil.
b) Crée une erreur.
c) Retourne 0.
Sur la détection du retour du joueur :
À quoi sert player.CharacterAdded:Connect(...) ?
a) Exécuter une fonction quand un joueur réapparaît dans la partie.
La voiture robotisée UNIHIKER K10 est une plateforme d’apprentissage conçue pour t’initier à la programmation et à l’intelligence artificielle. Elle associe le châssis Maqueen Plus V3 à la carte de contrôle principale UNIHIKER K10, intégrant des technologies telles que le contrôle, l’affichage graphique, la reconnaissance vocale, la synthèse vocale, le traitement d’images et la communication sans fil. Elle te permet de progresser au codage des robots en maîtrisant l’interaction avec le matériel, les applications de capteurs et d’autres compétences clés.
Cette voiture robotisée excelle non seulement dans la conduite et la perception de l’environnement, mais elle prend également en charge des interactions multimodales telles que la lumière, le son et l’affichage, rendant l’apprentissage plus ludique et immersif.
L’objectif est le pilotage de ton maqueen piloté par l carte micro:bit avec le gamepad équipé d’une micro:bit
Introduction au matériel
1. Châssis intelligent Maqueen Plus V3
5 capteurs de suivi de ligne : Prend en charge la reconnaissance des lignes noires et le suivi de trajectoire pour les tâches de suivi de ligne intelligentes.
2 capteurs de lumière : détectent la luminosité ambiante pour un éclairage intelligent ou un contrôle du comportement sensible à la lumière.
Capteur laser matriciel : utilise 64 points laser pour l’évitement d’obstacles et la détection de falaises avec une précision millimétrique.
Phares et éclairage d’ambiance RGB pour voiture : 16 millions de couleurs personnalisables pour une meilleure visibilité et un retour d’information précis.
Buzzer : Émet des alertes sonores pour une meilleure interaction homme-machine.
Moteurs métalliques détachables : Parfaitement adaptés pour une rotation fluide sans calage.
Introduction au logiciel
Mind+ est un logiciel de programmation graphique facile à utiliser. Compatible avec de nombreuses plateformes matérielles, il propose un large éventail de modules et de ressources de programmation.
Interface graphique intuitive : Mind+ propose une interface glisser-déposer qui permet de créer des programmes sans écrire de code complexe. Cette conception intuitive facilite grandement la prise en main et permet aux débutants de se familiariser rapidement avec le logiciel.
Compatibilité matérielle étendue : Mind+ prend en charge une variété de périphériques, notamment le Maqueen Plus V3 et l’UNIHIKER K10.
Modules de programmation riches : Le logiciel propose un ensemble varié de modules couvrant le contrôle de mouvement, le traitement des données de capteurs, l’affichage graphique, la lecture audio, et bien plus encore.
L’interface de Mind+ comporte 8 zones principales : barre de menu, sélecteur de mode, outils rapides, blocs de commandes, zone de script, zone de code, extensions et moniteur série.
Apprendre à programmer deux robots (un Gamepad et un Maqueen) pour qu’ils communiquent sans fil via la radio Micro:bit. Tu vas :
Utiliser les entrées du Gamepad (boutons et joystick) pour contrôler le Maqueen.
Envoyer des commandes depuis le Gamepad (avec une Micro:bit).
Recevoir et exécuter ces commandes sur le Maqueen (avec une autre Micro:bit).
Matériel nécessaire
Élément
Quantité
Rôle
Micro:bit
2
Une pour le Gamepad, une pour le Maqueen.
Robot Maqueen
1
Robot à piloter.
Gamepad
1
Contrôleur avec boutons et joystick (ex: Micro:bit Gamepad ou un Gamepad externe compatible).
Piles
2 x 2 (AAA)
Alimentation des Micro:bit.
Câbles USB
2
Pour programmer les Micro:bit.
Étape 1 : Comprendre la communication radio Micro:bit
La Micro:bit permet d’envoyer et recevoir des messages sans fil via un canal radio (de 1 à 7).
Un seul canal peut être utilisé à la fois par un groupe de Micro:bit.
Si plusieurs groupes travaillent en même temps, chaque groupe doit choisir un canal différent (ex: groupe 1 = canal 1, groupe 2 = canal 2, etc.).
Instructions radio de base :
Programmer le Gamepad (Émetteur)
Passez en mode téléchargement : tous les projets de ce cours utilisent ce mode.
Ajouter la carte de contrôle principale : « Extensions » > « Cartes » > « MICRO:BIT »
Ajoutez la carte d’extension : « Extensions » > «User Ext » > «gamepad »
Le Gamepad va envoyer des commandes au Maqueen en fonction des boutons et du joystick.
Active la radio et définit le canal 1 (à adapter selon ton groupe).
Détecte les boutons pressés du gamepad :
Sur le gamepad utilise les instructions (NEW) button pour envoyer la commande sur l’appui d’un bouton ou l’utilisation du joystick :
Envoie des commandes comme « forward » pour avancer.
Ajoute une instruction d’affichage pour vérifier :
A toi de trouver le programme pour piloter ton robot.
avancer
reculer
tourner à droite
tourner à gauche
Programmer le Maqueen (Récepteur)
Le Maqueen va recevoir les commandes du Gamepad et agir en conséquence (avancer, reculer, tourner, etc.).
Ajoute les extensions :.
Ajouter la carte de contrôle principale : « Extensions » > « Cartes » > « MICRO:BIT »
Ajoutez la carte d’extension : « Extensions » > « Carte d’extension » ou « shield board » > « Maqueen Plus V2/V3 »
Utilise les mêmes instructions de transmission des ordres par radio sauf que tu vas utiliser une instruction de réception when received.
Active la radio et définit le canal 1 (à adapter selon ton groupe).
Appelle when received la fonction puis serial in stringquand un message est reçu.
Puis teste la commande reçue en l’occurrence forward :
Vérifie la bonne réception du message reçu en utilisant une instruction pour activer les LEDs de la micro:bit.
Utilise ces commandes pour actionner les moteurs du Maqueen :
Par exemple pour accepter la commande forward et faire avancer le robot :
A toi de trouver comment programmer le Maqueen pour le faire reculer, tourner à droite, tourner à gauche ….
Utilise tes connaissances pour améliorer ton robot en utilisant le Joystick pour piloter le robot, rajoute une commande pour l’arrêter, allumer les LEDs …
Comment gérer un part de pouvoir aléatoire : Aléatoirement, le part change de couleur et peut être traversé pour acquérir un pouvoir puis redevient compact sans laisser la possibilité d’acquérir un nouveau pouvoir.
Comprendre comment utiliser TweenService pour animer une partie (Part) dans Roblox, en changeant sa transparence, sa couleur, et ses propriétés physiques (comme CanCollide et CanTouch).
-- Récupérer le dossier et la partie "PowerPart" dans le Workspace
local powersFolder = workspace:WaitForChild("PowersFolder")
local powerPart = powersFolder:WaitForChild("PowerPart")
-- Variable pour contrôler l'exécution de la boucle (non utilisée ici, mais utile pour arrêter le script si besoin)
local isPowerActive = true
local POWER_DURATION = 5 -- Durée de l'animation "power" (en secondes)
local MAX_WITHOUT_POWER_DURATION = 10 -- Durée maximale entre deux activations (en secondes)
local MIN_WITHOUT_POWER_DURATION = 3 -- Durée minimale entre deux activations (en secondes)
-- Boucle infinie pour activer l'animation aléatoirement
task.spawn(function()
while isPowerActive do
-- Attendre un temps aléatoire entre MIN_WITHOUT_POWER_DURATION et MAX_WITHOUT_POWER_DURATION
task.wait(math.random(MIN_WITHOUT_POWER_DURATION, MAX_WITHOUT_POWER_DURATION))
-- Inverser les propriétés CanCollide et CanTouch
powerPart.CanCollide = not powerPart.CanCollide
powerPart.CanTouch = not powerPart.CanCollide
-- Attendre que l'animation soit terminée
task.wait(POWER_DURATION)
-- Réactiver les collisions et le toucher
powerPart.CanCollide = not powerPart.CanCollide
powerPart.CanTouch = not powerPart.CanCollide
end
end)
-- Détecter quand un joueur touche la partie
powerPart.Touched:Connect(function(hit)
print("La partie PowerPart a été touchée !")
end)
Boucle infinie pour activer l’animation aléatoirement
task.spawn(function() ... end) : Crée une nouvelle tâche (thread) pour exécuter la boucle sans bloquer le reste du script.
while isPowerActive do ... end : Boucle infinie (tant que isPowerActive est true).
Attend un temps aléatoire entre MIN_WITHOUT_POWER_DURATION (3 secondes) et MAX_WITHOUT_POWER_DURATION (10 secondes).
powerPart.CanCollide = not powerPart.CanCollide :
Inverse la valeur de CanCollide (si c’était true, ça devient false, et vice versa).
task.wait(POWER_DURATION) : Temps d’action du pouvoir
Réactivation des propriétés :
Après la fin de l’animation, on réactive CanCollide et CanTouch.
Ajouter dans cette partie de code le pouvoir à donner au joueur :
-- Détecter quand un joueur touche la partie
powerPart.Touched:Connect(function(hit)
print("La partie PowerPart a été touchée !")
end)
Création de l’animation avec TweenService
La part change de couleur lorsque le pouvoir est possible :
-- Récupérer le dossier et la partie "PowerPart" dans le Workspace
local powersFolder = workspace:WaitForChild("PowersFolder")
local powerPart = powersFolder:WaitForChild("PowerPart")
-- Variable pour contrôler l'exécution de la boucle (non utilisée ici, mais utile pour arrêter le script si besoin)
local isPowerActive = true
-- Service pour créer des animations fluides
local TweenService = game:GetService("TweenService")
-- Durées et couleurs pour les animations
local POWER_DURATION = 5 -- Durée de l'animation "power" (en secondes)
local MAX_WITHOUT_POWER_DURATION = 10 -- Durée maximale entre deux activations (en secondes)
local MIN_WITHOUT_POWER_DURATION = 3 -- Durée minimale entre deux activations (en secondes)
local POWER_COLOR = Color3.fromRGB(0, 255, 0) -- Couleur verte pour l'état "power"
local NO_POWER_COLOR = Color3.fromRGB(255, 0, 0) -- Couleur rouge pour l'état "sans power"-- Configurer la partie "PowerPart"
powerPart.Anchored = true -- Empêcher la partie de bouger
powerPart.Transparency = 0 -- Rendre la partie complètement opaque
powerPart.CanCollide = true -- Permettre les collisions avec la partie
powerPart.CanTouch = true -- Permettre de détecter les touches sur la partie
powerPart.Color = NO_POWER_COLOR -- Couleur initiale (rouge)-- Créer une animation (Tween) pour la partie
-- Cette animation change la transparence, la couleur et désactive les collisions
local powerTween = TweenService:Create(
powerPart, -- Objet à animer
TweenInfo.new(
POWER_DURATION, -- Durée de l'animation
Enum.EasingStyle.Linear, -- Style d'animation (linéaire)
Enum.EasingDirection.InOut, -- Direction de l'animation (aller-retour)
0, -- Nombre de répétitions (0 = une seule fois)
true -- Joue l'animation en boucle (inversée)
),
{
Transparency = 0.8, -- La partie devient semi-transparente
CanCollide = false, -- Désactive les collisions
Color = POWER_COLOR -- Change la couleur en vert
}
)
-- Boucle infinie pour activer l'animation aléatoirement
task.spawn(function()
while isPowerActive do
-- Attendre un temps aléatoire entre MIN_WITHOUT_POWER_DURATION et MAX_WITHOUT_POWER_DURATION
task.wait(math.random(MIN_WITHOUT_POWER_DURATION, MAX_WITHOUT_POWER_DURATION))
-- Jouer l'animation
powerTween:Play()
-- Inverser les propriétés CanCollide et CanTouch
powerPart.CanCollide = not powerPart.CanCollide
powerPart.CanTouch = not powerPart.CanCollide
-- Attendre que l'animation soit terminée
powerTween.Completed:Wait()
-- Réactiver les collisions et le toucher
powerPart.CanCollide = not powerPart.CanCollide
powerPart.CanTouch = not powerPart.CanCollide
end
end)
-- Détecter quand un joueur touche la partie
powerPart.Touched:Connect(function(hit)
print("La partie PowerPart a été touchée !")
end)
Configuration de la PowerPart
La PowerPart est configurée avec les propriétés suivantes :
Anchored = true : Empêche la partie de bouger (elle reste fixe dans le monde).
Transparency = 0 : La partie est complètement opaque (visible à 100%).
CanCollide = true : Les joueurs et objets peuvent entrer en collision avec la partie.
CanTouch = true : La partie peut détecter les touches (pour l’événement Touched).
Color = NO_POWER_COLOR : La couleur initiale est rouge (état « sans power »).
Création de l’animation avec TweenService
TweenService permet de créer des animations fluides pour modifier les propriétés d’un objet sur une durée donnée.
Paramètres de TweenService:Create :
Objet à animer : powerPart (la partie à animer).
TweenInfo.new : Définit les propriétés de l’animation :
a) Pour exécuter la boucle sans bloquer le reste du script.
b) Pour arrêter le script.
c) Pour créer un nouveau joueur.
Que fait math.random(MIN_WITHOUT_POWER_DURATION, MAX_WITHOUT_POWER_DURATION) ?
a) Génère un nombre aléatoire entre MIN_WITHOUT_POWER_DURATION et MAX_WITHOUT_POWER_DURATION.
b) Attend exactement 5 secondes.
c) Désactive la partie. Réponse : a)
Que fait powerPart.Touched:Connect(function(hit) ... end) ?
a) Exécute une fonction quand un objet touche la PowerPart.
b) Change la taille de la PowerPart.
c) Supprime la PowerPart.
Pourquoi inverse-t-on CanCollide et CanTouch dans la boucle ?
a) Pour alterner entre un état où la partie est solide/touchable et un état où elle ne l’est pas.
b) Pour changer la couleur de la partie.
c) Pour supprimer la partie.
Changer la taille de la partie pendant l’animation
Objectif : Faire grandir ou rétrécir la PowerPart pendant l’animation.
Comment faire ?
Ajoute Size = Vector3.new(10, 10, 10) dans les propriétés du Tween :luaCopier
-- Récupérer le dossier et la partie "PowerPart" dans le Workspace
local powersFolder = workspace:WaitForChild("PowersFolder")
local powerPart = powersFolder:WaitForChild("PowerPart")
-- Variable pour contrôler l'exécution de la boucle (non utilisée ici, mais utile pour arrêter le script si besoin)
local isPowerActive = true
-- Service pour créer des animations fluides
local TweenService = game:GetService("TweenService")
-- Durées et couleurs pour les animations
local POWER_DURATION = 5 -- Durée de l'animation "power" (en secondes)
local MAX_WITHOUT_POWER_DURATION = 10 -- Durée maximale entre deux activations (en secondes)
local MIN_WITHOUT_POWER_DURATION = 3 -- Durée minimale entre deux activations (en secondes)
local POWER_COLOR = Color3.fromRGB(0, 255, 0) -- Couleur verte pour l'état "power"
local NO_POWER_COLOR = Color3.fromRGB(255, 0, 0) -- Couleur rouge pour l'état "sans power"
-- Configurer la partie "PowerPart"
powerPart.Anchored = true -- Empêcher la partie de bouger
powerPart.Transparency = 0 -- Rendre la partie complètement opaque
powerPart.CanCollide = true -- Permettre les collisions avec la partie
powerPart.CanTouch = true -- Permettre de détecter les touches sur la partie
powerPart.Color = NO_POWER_COLOR -- Couleur initiale (rouge)
-- Créer une animation (Tween) pour la partie
-- Cette animation change la transparence, la couleur et désactive les collisions
local powerTween = TweenService:Create(
powerPart, -- Objet à animer
TweenInfo.new(
POWER_DURATION, -- Durée de l'animation
Enum.EasingStyle.Linear, -- Style d'animation (linéaire)
Enum.EasingDirection.InOut, -- Direction de l'animation (aller-retour)
0, -- Nombre de répétitions (0 = une seule fois)
true -- Joue l'animation en boucle (inversée)
),
{
Transparency = 0.8, -- La partie devient semi-transparente
CanCollide = false, -- Désactive les collisions
Color = POWER_COLOR,
Size = Vector3.new(powerPart.Size.X + 10, powerPart.Size.Y + 10, powerPart.Size.Z)
}
)
-- Boucle infinie pour activer l'animation aléatoirement
task.spawn(function()
while isPowerActive do
-- Attendre un temps aléatoire entre MIN_WITHOUT_POWER_DURATION et MAX_WITHOUT_POWER_DURATION
task.wait(math.random(MIN_WITHOUT_POWER_DURATION, MAX_WITHOUT_POWER_DURATION))
-- Jouer l'animation
powerTween:Play()
-- Inverser les propriétés CanCollide et CanTouch
powerPart.CanCollide = not powerPart.CanCollide
powerPart.CanTouch = not powerPart.CanCollide
-- Attendre que l'animation soit terminée
powerTween.Completed:Wait()
-- Réactiver les collisions et le toucher
powerPart.CanCollide = not powerPart.CanCollide
powerPart.CanTouch = not powerPart.CanCollide
end
end)
-- Détecter quand un joueur touche la partie
powerPart.Touched:Connect(function(hit)
print("La partie PowerPart a été touchée !")
end)
Dans Roblox Studio, la Baseplate est une pièce fondamentale de ton monde. C’est une grande plaque plane (généralement verte) qui sert de sol de base pour ton jeu. Elle permet aux joueurs et aux objets de :
Se tenir debout (sans elle, les personnages tombent dans le vide !).
Avoir un point de référence pour construire ton niveau.
Éviter les erreurs liées à l’absence de sol (ex: les personnages qui tombent indéfiniment).
Le script : Supprimer la Baseplate
Voici le script que tu as fourni, commenté pour comprendre son fonctionnement :
-- Récupérer la Baseplate dans le Workspace
local baseplate = workspace:WaitForChild("Baseplate")
-- Supprimer la Baseplate
baseplate:Destroy()
Explications :
workspace:WaitForChild("Baseplate") :
Attend que la Baseplate existe dans le Workspace avant de continuer.
Si la Baseplate n’existe pas, le script attend qu’elle soit créée (par exemple, si elle est ajoutée plus tard).
baseplate:Destroy() :
Supprime la Baseplate du jeu.
Résultat : Plus de sol → les personnages et les objets tombent dans le vide !
Pourquoi est-ce important de comprendre la Baseplate ?
1. La Baseplate comme sol de base
Sans Baseplate, ton jeu n’a aucun sol par défaut.
Les joueurs et les objets tombent indéfiniment (ce qui peut être amusant pour un jeu de chute libre, mais pas pour un jeu classique !).
2. Construire ton niveau autour de la Baseplate
La Baseplate est souvent le point de départ pour construire ton monde.
Tu peux :
Ajouter des objets (murs, plateformes, etc.) au-dessus de la Baseplate.
Modifier sa taille pour l’adapter à ton jeu.
Changer sa couleur pour correspondre au thème de ton jeu.
3. Cas d’usage avancés
Supprimer la Baseplate :
Utile pour créer des jeux sans sol (ex: un jeu de vol libre, un jeu spatial).
Attention : Si tu supprimes la Baseplate, assure-toi que ton jeu a un autre sol (ex: des plateformes flottantes).
Remplacer la Baseplate :
Tu peux créer ton propre sol (ex: une grande Part plate) et supprimer la Baseplate par défaut.
Étape par étape : Manipuler la Baseplate dans Roblox Studio
1. Voir la Baseplate par défaut
Ouvre Roblox Studio et crée un nouveau jeu.
Dans l’arborescence (Explorer), tu verras une Baseplate sous Workspace.
2. Supprimer la Baseplate (comme dans le script)
Méthode 1 : Via le script
Copie le script ci-dessus dans un Script (ex: dans ServerScriptService).
Lance le jeu : la Baseplate disparaît, et tout tombe !
Méthode 2 : Manuellement
Dans l’arborescence, fais un clic droit sur Baseplate → Delete.
Résultat : identiques à la méthode 1.
3. Créer un sol personnalisé
Si tu veux supprimer la Baseplate mais garder un sol :
Ajoute une nouvelle Part :
Clic droit sur Workspace → Insert Object → Part.
Redimensionne la Part :
Dans les propriétés, modifie Size pour qu’elle soit grande (ex: Vector3.new(1000, 1, 1000)).
Positionne-la au sol :
Modifie Position pour qu’elle soit à Y = 0 (même niveau que la Baseplate).
Supprime la Baseplate :
Utilise le script ou supprime-la manuellement.
QCM : Vérifie ta compréhension !
À quoi sert la Baseplate dans Roblox ?
a) À servir de sol de base pour les joueurs et les objets.
b) À jouer des sons.
c) À créer des personnages.
Que fait workspace:WaitForChild("Baseplate") ?
a) Attend que la Baseplate existe dans le Workspace.
b) Crée une nouvelle Baseplate.
c) Supprime la Baseplate.
Que se passe-t-il si tu supprimes la Baseplate sans remplacer le sol ?
a) Les joueurs et les objets tombent dans le vide.
b) Le jeu plante.
c) Rien ne change.
Comment créer un sol personnalisé après avoir supprimé la Baseplate ?
a) Ajouter une Part plate et grande dans Workspace.
b) Ajouter un Script.
c) Ajouter un ClickDetector.
Idées pour aller plus loin
1. Créer un jeu sans sol
Objectif : Utiliser l’absence de sol pour un jeu de chute libre ou de vol.
Exemple :
Supprime la Baseplate.
Ajoute des plateformes flottantes pour que les joueurs puissent sauter de l’une à l’autre.
2. Remplacer la Baseplate par un sol personnalisé
Objectif : Avoir un sol avec une texture ou une couleur spécifique.
Comment faire ?
Ajoute une Part plate et grande.
Modifie sa couleur ou sa texture dans les propriétés.
Apprendre à utiliser ParticleEmitter pour ajouter des effets visuels spectaculaires à ton jeu Roblox. Dans ce tutoriel, on va se concentrer uniquement sur l’ajout et la personnalisation des particules pour rendre le jeu plus beau et immersif.
Pourquoi utiliser des particules ?
Les particules sont des petits effets visuels (comme des étincelles, de la fumée, des paillettes, etc.) qui peuvent :
Rendre ton jeu plus réaliste (ex: étincelles quand un joueur touche un objet magique).
Ajouter du feedback visuel (ex: montrer qu’une action a bien eu lieu).
Créer une ambiance (ex: un effet de poussière, de feu, ou de magie).
Dans ce script, on utilise un ParticleEmitter pour afficher un effet quand un joueur touche la ScalePart.
Ajouter un ParticleEmitter à ta ScalePart
Pour que le script fonctionne, tu dois ajouter un ParticleEmitter à ta ScalePart dans Roblox Studio.
Comment faire ?
Ouvre Roblox Studio et ton jeu.
Sélectionne ta ScalePart dans l’arborescence (Workspace > ScaleFolder > ScalePart).
Ajoute un ParticleEmitter :
Clic droit sur ScalePart → Insert Object → ParticleEmitter.
Un nouvel objet ParticleEmitter apparaît sous ScalePart.
Personnalise les particules :
Sélectionne le ParticleEmitter dans l’arborescence.
Dans les propriétés (à droite), tu peux modifier : Propriété Description Exemple de valeur Enabled Active/désactive l’effet. false (on l’active via le script) Texture L’apparence des particules (image). rbxassetid://242840127 (étincelles) Color La couleur des particules. Color3.fromRGB(255, 215, 0) (or) Size La taille des particules. NumberSequence.new(0.5)Lifetime Durée de vie des particules (en secondes). NumberRange.new(1, 2)Speed Vitesse des particules. NumberRange.new(5, 10)EmissionDirection Direction dans laquelle les particules sont émises. Enum.NormalId.Top (vers le haut) Rate Nombre de particules émises par seconde. 10
Exemple de configuration pour des étincelles magiques :
Les particules disparaissent après 1 à 1.5 seconde.
Speed
NumberRange.new(3, 8)
Vitesse aléatoire pour un effet naturel.
EmissionDirection
Enum.NormalId.Top
Les particules montent.
Rate
20
20 particules par seconde.
Comprendre le code lié aux particules
Voici la partie du script qui gère les particules (le reste du script est expliqué dans les tutoriels précédents) :
-- Dans la fonction part.Touched:Connect, après avoir modifié la taille du joueur :
local particle = part:FindFirstChildOfClass("ParticleEmitter") -- Cherche un ParticleEmitter dans la partie
-- Appliquer la taille cible au personnage
humanoid.BodyHeightScale.Value = targetScale
humanoid.BodyWidthScale.Value = targetScale
humanoid.BodyDepthScale.Value = targetScale
humanoid.HeadScale.Value = targetScale
-- ACTIVER LES PARTICULES quand le joueur touche la partie
if particle then part.ParticleEmitter.Enabled = true end
-- Désactiver les particules après le cooldown
task.delay(COOLDOWN, function()
cooldowns[player] = nil
if particle then part.ParticleEmitter.Enabled = false end -- Désactive les particules
end)
Explications :
part:FindFirstChildOfClass("ParticleEmitter")
Cherche un objet de type ParticleEmitter dans la ScalePart.
Si un ParticleEmitter existe, il est stocké dans la variable particle.
part.ParticleEmitter.Enabled = true
Active l’effet de particules quand un joueur touche la ScalePart.
Les particules apparaissent immédiatement et restent visibles tant que Enabled est à true.
part.ParticleEmitter.Enabled = false
Désactive l’effet de particules après le COOLDOWN (1 seconde dans ce script).
Cela évite que les particules restent actives en permanence.
Tester et personnaliser les particules
Lance le jeu dans Roblox Studio.
Touche la ScalePart :
Ton personnage rétrécit ou grandit.
Un effet de particules apparaît (si tu as bien configuré le ParticleEmitter).
Expérimente avec les propriétés :
Change la texture pour des effets différents (fumée, feu, bulles, etc.).
Exemples d’IDs de textures :
Fumée : rbxassetid://242840156
Feu : rbxassetid://242840140
Bulles : rbxassetid://242840119
Change la couleur pour correspondre au thème de ton jeu.
Ajuste la taille et la vitesse pour un effet plus ou moins intense.
Idées pour aller plus loin avec les particules
Voici quelques idées pour améliorer ton jeu avec des ParticleEmitter :
1. Particules différentes selon l’action
Objectif : Utiliser des particules différentes quand le joueur rétrécit ou grandit.
Comment faire ?
Ajoute deux ParticleEmitter à ta ScalePart :
Un pour le rétrécissement (ex: particules bleues).
Un pour la restauration (ex: particules vertes).
Dans le script, active uniquement le bon ParticleEmitter selon l’action :luaCopierif originalScale then -- Restaurer : activer les particules vertes part.ParticleEmitterGreen.Enabled = true else -- Rétrécir : activer les particules bleues part.ParticleEmitterBlue.Enabled = true end
2. Particules qui suivent le joueur
Objectif : Faire apparaître des particules autour du joueur quand il rétrécit.
Comment faire ?
Ajoute un ParticleEmitterdans le personnage du joueur (ex: dans son HumanoidRootPart).
Rajoute cette fonction à ton script
local function addParticle(character)
print("adding particle")
local part = character:FindFirstChild("HumanoidRootPart")
if not part then return end
print("found part")
local particle = Instance.new("ParticleEmitter")
particle.Texture = "rbxassetid://248625108" -- mets ton ID d'image ici
particle.Lifetime = NumberRange.new(5, 10)
particle.Rate = 20
particle.Speed = NumberRange.new(5, 5)
particle.Color = ColorSequence.new(Color3.new(1, 1, 1))
particle.Parent = part
task.delay(COOLDOWN, function()
particle:Destroy()
end)
end
3. Particules avec un son
Objectif : Ajouter un son quand les particules apparaissent.
Comment faire ?
Ajoute un objet Sound à ta ScalePart.
Joue le son quand les particules sont activées :luaCopierlocal sound = part:FindFirstChildOfClass("Sound") if sound then sound:Play() end
QCM : Vérifie ta compréhension !
À quoi sert un ParticleEmitter dans Roblox ?
a) À créer des effets visuels comme des étincelles ou de la fumée.
b) À faire bouger une partie.
c) À jouer un son.
Que fait part:FindFirstChildOfClass("ParticleEmitter") ?
a) Crée un nouveau ParticleEmitter.
b) Cherche un ParticleEmitter dans la part.
c) Supprime un ParticleEmitter.
Pourquoi désactive-t-on le ParticleEmitter après le cooldown ?
a) Pour éviter que les particules restent actives en permanence.
b) Pour économiser de la mémoire.
c) Pour changer la couleur des particules.
Où peut-on ajouter un ParticleEmitter dans Roblox Studio ?
a) Dans une Part ou un Model.
b) Dans ServerScriptService.
c) Dans Workspace uniquement.
Quelle propriété du ParticleEmitter permet de changer l’apparence des particules ?
Créer des objets (ex: des Part) dans un dossier (MessagesFolder).
Chaque objet a un message personnalisé stocké dans un attribut (Message).
Quand un joueur clique sur un objet, son personnage affiche le message dans une bulle de chat au-dessus de sa tête.
Comprendre le but du script
But :
Permettre aux joueurs de cliquer sur des objets pour afficher des messages personnalisés.
Utiliser les attributs pour stocker des données (ici, le message) directement sur les objets.
Utiliser GetDescendants pour trouver tous les ClickDetector dans un dossier, même s’ils sont imbriqués.
Concepts clés :
GetDescendants : Récupérer tous les objets enfants (y compris les enfants des enfants, etc.).
GetAttribute : Lire une donnée personnalisée stockée sur un objet (ex: un message).
ClickDetector : Détecter quand un joueur clique sur un objet.
Chat:Chat() : Afficher un message dans une bulle de chat au-dessus de la tête du joueur.
Préparer le jeu dans Roblox Studio
Pour tester le script, suis ces étapes :
Créer un dossier :
Dans Workspace, crée un dossier nommé MessagesFolder.
Ajouter des Part :
Ajoute plusieurs Part dans MessagesFolder.
Pour chaque Part :
Ajoute un attribut Message (de type String) avec un texte différent (ex: "Bonjour !", "Salut !", "Hello !").
Ajoute un ClickDetector comme enfant de la Part (clic droit sur la Part → Insert Object → ClickDetector).
Ajouter le script :
Crée un Script dans ServerScriptService et copie-y le code fourni.
Tester le jeu :
Lance le jeu et clique sur les Part :
Une bulle de chat devrait apparaître au-dessus de la tête de ton personnage avec le message stocké dans l’attribut.
Comment créer un attribut pour un message personnalisé :
Le script :
Voici le script commenté pour comprendre chaque partie :
-- Récupérer le service de chat de Roblox
local Chat = game:GetService("Chat")
-- Récupérer le dossier contenant les objets cliquables
local folder = workspace:WaitForChild("MessagesFolder")
-- Parcourir TOUS les descendants du dossier (y compris les enfants des enfants, etc.)
for _, clickDetector in ipairs(folder:GetDescendants()) do
-- Vérifier si l'objet actuel est un ClickDetector
if not clickDetector:IsA("ClickDetector") then continue end
-- Récupérer la partie (Part) parente du ClickDetector
local part = clickDetector.Parent
-- Récupérer le message stocké dans l'attribut "Message" de la partie
local message = part and part:GetAttribute("Message")
-- Si la partie n'a pas d'attribut "Message", on passe à l'itération suivante
if not message then continue end
-- Connecter une fonction au clic du ClickDetector
clickDetector.MouseClick:Connect(function(player)
-- Récupérer le personnage du joueur (attendre qu'il existe si nécessaire)
local character = player.Character or player.CharacterAdded:Wait()
-- Trouver la tête du personnage
local head = character:FindFirstChild("Head")
if not head then return end -- Si pas de tête, on arrête
-- Afficher le message dans une bulle de chat au-dessus de la tête
Chat:Chat(head, player.Name .. " " .. message)
end)
end
Explications détaillées
1. La puissance de GetChildren et GetDescendants
GetChildren :
Récupère uniquement les enfants directs d’un objet.
Exemple : Si folder contient 3 Part et que chaque Part contient un ClickDetector, folder:GetChildren() ne retournera que les 3 Part (pas les ClickDetector).
GetDescendants :
Récupère tous les descendants (enfants, petits-enfants, etc.) d’un objet.
Exemple : Avec la même structure, folder:GetDescendants() retournera les 3 Partet les 3 ClickDetector.
Pourquoi c’est puissant ?
On peut trouver tous les objets d’un certain type (ex: tous les ClickDetector) même s’ils sont imbriqués profondément dans la hiérarchie.
Dans ce script, on utilise GetDescendants pour trouver tous les ClickDetector dans MessagesFolder, peu importe où ils sont placés.
Comparaison : Méthode Profondeur Exemple d’utilisation GetChildren 1 niveau Récupérer les Part directement dans folder. GetDescendants Tous niveaux Trouver tous les ClickDetector dans folder.
2. L’utilité des attributs (GetAttribute)
Qu’est-ce qu’un attribut ?
Un attribut est une donnée personnalisée que tu peux attacher à un objet Roblox (ex: une Part).
Exemple : Tu peux stocker un Message sur une Part pour savoir quel texte afficher quand un joueur clique dessus.
Pourquoi utiliser des attributs ?
Flexibilité : Tu peux stocker n’importe quelle donnée (texte, nombre, booléen) directement sur un objet.
Organisation : Pas besoin de créer des variables globales ou des tableaux pour associer des données à des objets.
Performance : Les attributs sont optimisés pour être lus et modifiés rapidement.
Comment ajouter un attribut à une Part ?
Dans Roblox Studio :
Sélectionne une Part.
Dans les propriétés, cherche la section Attributes.
Ajoute un nouvel attribut (ex: Message de type String) et donne-lui une valeur (ex: "Bonjour !").
Dans le script :
part:GetAttribute("Message") récupère la valeur de l’attribut Message de la Part.
Si l’attribut n’existe pas, GetAttribute retourne nil.
3. Le fonctionnement du ClickDetector
Qu’est-ce qu’un ClickDetector ?
Un objet invisible qui détecte les clics de souris sur une Part ou un Model.
Il doit être enfant de la Part ou du Model que tu veux rendre cliquable.
Comment ça marche ?
Quand un joueur clique sur une Part contenant un ClickDetector, l’événement MouseClick est déclenché.
On peut connecter une fonction à cet événement pour exécuter du code quand le joueur clique.
Exemple dans le script :luaCopierclickDetector.MouseClick:Connect(function(player) -- Code exécuté quand un joueur clique sur la partie print(player.Name .. " a cliqué !") end)
player est le joueur qui a cliqué.
La fonction est appelée automatiquement quand un clic est détecté.
Pourquoi utiliser ClickDetector ?
Simplicité : Pas besoin de gérer manuellement les clics avec des calculs de position.
Précision : Roblox gère automatiquement la détection des clics, même si la Part bouge ou tourne.
4. Afficher un message dans le chat
Chat:Chat(head, message) :
Affiche une bulle de chat au-dessus de la Head du personnage.
head : La partie Head du personnage (où la bulle apparaîtra).
message : Le texte à afficher (ex: "Bonjour !").
Exemple dans le script :luaCopierChat:Chat(head, player.Name .. " " .. message)
Affiche un message comme : "Joueur1 Bonjour !".
À toi de jouer !
Modifie les messages :
Change les valeurs des attributs Message sur tes Part et observe le résultat.
Ajoute des objets imbriqués :
Crée un Model dans MessagesFolder, puis ajoute une Part avec un ClickDetector et un attribut Messageà l’intérieur du Model.
Vérifie que le script fonctionne toujours (grâce à GetDescendants !).
Teste avec plusieurs joueurs :
Ouvre deux fenêtres de test et vérifie que chaque joueur voit ses propres messages.
QCM pour vérifier la compréhension
Sur GetChildren et GetDescendants :
Quelle méthode permet de récupérer tous les objets, même imbriqués, dans un dossier ?
a) GetChildren
b) GetDescendants
c) GetAll
Si folder contient une Part qui contient un ClickDetector, que retourne folder:GetChildren() ?
a) La Part et le ClickDetector.
b) Seulement la Part.
c) Seulement le ClickDetector.
Pourquoi utilise-t-on GetDescendants dans ce script ?
a) Pour trouver tous les ClickDetector, même s’ils sont dans des Model imbriqués.
b) Pour supprimer les objets.
c) Pour changer la couleur des objets.
Sur les attributs (GetAttribute) :
À quoi sert part:GetAttribute("Message") ?
a) À récupérer la valeur de l’attribut Message de la Part.
b) À supprimer l’attribut Message.
c) À créer un nouvel attribut.
Où peut-on ajouter un attribut à une Part dans Roblox Studio ?
a) Dans la section Attributes des propriétés.
b) Dans la section Script.
c) Dans la section Model.
Que retourne GetAttribute si l’attribut n’existe pas ?
a) nil
b) 0
c) Une erreur.
Sur le ClickDetector :
Qu’est-ce qu’un ClickDetector ?
a) Un objet qui détecte les clics sur une Part.
b) Un objet qui change la couleur d’une Part.
c) Un objet qui joue un son.
Où doit-on placer un ClickDetector pour qu’il fonctionne ?
a) Comme enfant d’une Part ou d’un Model.
b) Dans Workspace.
c) Dans ServerScriptService.
Que fait clickDetector.MouseClick:Connect(function(player) ... end) ?
a) Exécute une fonction quand un joueur clique sur la Part.
b) Supprime le ClickDetector.
c) Change la taille de la Part.
Sur le chat :
À quoi sert Chat:Chat(head, message) ?
a) À afficher une bulle de chat au-dessus de la tête du personnage.
b) À envoyer un message dans le chat global.
c) À supprimer le personnage.
Résumé des concepts appris
Concept
Explication
Exemple dans le script
GetDescendants
Récupère tous les descendants d’un objet (enfants, petits-enfants, etc.).
folder:GetDescendants()
Attributs
Données personnalisées stockées sur un objet.
part:GetAttribute("Message")
ClickDetector
Détecte les clics sur une Part ou un Model.
clickDetector.MouseClick:Connect(...)
Chat:Chat
Affiche une bulle de chat au-dessus de la tête d’un personnage.
Chat:Chat(head, message)
Boucles for
Parcourt une liste d’objets.
for _, clickDetector in ipairs(...) do
Conditions
Exécute du code si une condition est vraie.
if not clickDetector:IsA("ClickDetector") then continue end
Quand un joueur touche une partie (ScalePart), sa taille alterne entre :
Réduction (taille = SCALEMINI).
Restauration (taille d’origine).
Un cooldown (COOLDOWN) empêche le joueur de déclencher l’effet trop souvent.
Le script gère aussi les joueurs qui quittent le jeu pour éviter les fuites de mémoire.
Comprendre le but du script
But :
Créer une partie (ScalePart) qui, quand un joueur la touche, alterne sa taille (rétrécit → restaure → rétrécit…).
Limiter la fréquence avec un cooldown (2 secondes).
Nettoyer les données des joueurs qui quittent le jeu pour éviter les bugs.
Concepts clés :
Variables : SCALEMINI, COOLDOWN.
Tableaux associatifs : cooldowns (pour le cooldown) et savedScales (pour stocker la taille d’origine).
Événements : Touched (pour détecter le contact) et PlayerRemoving (pour nettoyer les données).
Conditions : Vérifier si le joueur est déjà réduit (if originalScale then ...).
À toi de jouer !
Copie ce script dans un Script dans Roblox Studio (par exemple, dans ServerScriptService).
Crée les éléments nécessaires :
Un dossier ScaleFolder dans Workspace.
Une partie (Part) nommée ScalePart dans ce dossier.
Teste le jeu :
Lance le jeu et touche la ScalePart :
Ton personnage rétrécit à 0.3.
Attends 2 secondes et touche à nouveau : ta taille est restaurée.
Touche une 3ème fois : tu rétrécis à nouveau.
Teste avec 2 joueurs :
Vérifie que chaque joueur a son propre cooldown et sa propre taille sauvegardée.
Le script
Voici le script commenté pour comprendre chaque partie :
-- Services et objets nécessaires
local Players = game:GetService("Players") -- Service pour gérer les joueurs
-- Récupérer la partie et son dossier parent
local folder = workspace:WaitForChild("ScaleFolder") -- Dossier contenant la partie
local part = folder:WaitForChild("ScalePart") -- La partie à toucher
-- Variables globales
local SCALEMINI = 0.3 -- Taille réduite appliquée au contact
local COOLDOWN = 2 -- Temps d'attente (en secondes) avant de pouvoir re-déclencher
-- Tableaux pour gérer les états des joueurs
local cooldowns = {} -- [player] = true si le joueur est en cooldown
local savedScales = {} -- [player] = taille d'origine du joueur (si il est actuellement réduit)
-- Détecter quand un joueur touche la partie
part.Touched:Connect(function(hit)
-- Trouver le personnage du joueur qui a touché la partie
local character = hit:FindFirstAncestorOfClass("Model")
local player = character and Players:GetPlayerFromCharacter(character)
-- Ignorer si ce n'est pas un joueur (ex: un mob, un débris)
if not player then return end
-- VÉRIFIER LE COOLDOWN : Si le joueur est en cooldown, on arrête tout
if cooldowns[player] then return end
-- Trouver l'humanoïde du personnage (pour modifier sa taille)
local humanoid = character:FindFirstChildOfClass("Humanoid")
if not humanoid then return end
-- ACTIVER LE COOLDOWN pour ce joueur
cooldowns[player] = true
-- Récupérer la taille d'origine du joueur (si elle a été sauvegardée)
local originalScale = savedScales[player]
local targetScale -- Taille cible (soit SCALEMINI, soit la taille d'origine)
-- LOGIQUE FLIP/FLOP :
if originalScale then
-- Le joueur est déjà réduit : on restaure sa taille d'origine
targetScale = originalScale
savedScales[player] = nil -- Supprimer la taille sauvegardée
else
-- Le joueur n'est pas réduit : on sauvegarde sa taille et on l'applique SCALEMINI
savedScales[player] = humanoid.BodyHeightScale.Value
targetScale = SCALEMINI
end -- Appliquer la taille cible au personnage
humanoid.BodyHeightScale.Value = targetScale
humanoid.BodyWidthScale.Value = targetScale
humanoid.BodyDepthScale.Value = targetScale
humanoid.HeadScale.Value = targetScale
-- Après COOLDOWN secondes, réactiver la possibilité de déclencher l'effet
task.delay(COOLDOWN, function()
cooldowns[player] = nil
end)
end)
-- NETTOYAGE : Quand un joueur quitte le jeu, supprimer ses données
Players.PlayerRemoving:Connect(function(player)
cooldowns[player] = nil
savedScales[player] = nil
end)
Explications détaillées
1. Le mécanisme de flip/flop
Principe : Le script alterne la taille du joueur entre :
Réduction (SCALEMINI = 0.3) quand il touche la partie pour la première fois.
Restauration (taille d’origine) quand il la touche à nouveau.
Comment ça marche ?
Le tableau savedScales stocke la taille d’origine du joueur uniquement quand il est réduit.
Si savedScales[player] existe (originalScale), cela signifie que le joueur est déjà réduit → on restaure sa taille.
Sinon, on sauvegarde sa taille actuelle et on applique SCALEMINI.
Exemple concret :
1er contact : Le joueur a une taille normale (ex: 1.0). Le script sauvegarde 1.0 dans savedScales[player] et applique 0.3.
2ème contact : Le script voit que savedScales[player] = 1.0 existe → il restaure la taille à 1.0 et supprime savedScales[player].
3ème contact : savedScales[player] n’existe plus → le joueur est à nouveau réduit à 0.3.
2. Pourquoi un cooldown ?
Problème sans cooldown : Si un joueur touche la partie plusieurs fois en une seconde, sa taille changera trop vite (ex: rétrécir → restaurer → rétrécir en 0.1 seconde). Cela rendrait le jeu incontrôlable et peu amusant.
Solution avec cooldown :
cooldowns[player] = true bloque le joueur pendant COOLDOWN secondes (2 secondes ici).
Après ce délai, cooldowns[player] = nil permet au joueur de déclencher à nouveau l’effet.
Analogie : Imagine un interrupteur qui ne peut être actionné qu’une fois toutes les 2 secondes. Le cooldown, c’est comme ce délai de sécurité !
3. Pourquoi nettoyer les tableaux quand un joueur quitte ?
Problème sans nettoyage : Si un joueur quitte le jeu sans que ses données soient supprimées, les tableaux cooldowns et savedScales garderont des entrées inutiles.
Conséquences :
Fuites de mémoire : Les tableaux grossissent indéfiniment.
Bugs : Si un nouveau joueur rejoint avec le même player (rare mais possible), il pourrait hériter des données du joueur précédent.
Quand un joueur quitte, on supprime ses entrées dans les deux tableaux.
Cela garantit que les tableaux restent propres et efficaces.
Analogie : C’est comme ranger ton bureau après avoir fini tes devoirs : si tu ne ranges pas, ton bureau devient un bordel, et tu ne retrouves plus rien !
4. Autres concepts importants
FindFirstAncestorOfClass("Model") : Permet de remonter dans la hiérarchie de l’objet touché (hit) pour trouver le personnage (qui est un Model).
Exemple : Si hit est un bras du personnage, FindFirstAncestorOfClass("Model") retourne le personnage entier.
task.delay(COOLDOWN, function() ... end) : Exécute une fonction après un délai (COOLDOWN secondes). Ici, on réinitialise le cooldown du joueur.
Tableaux associatifs :
cooldowns et savedScales utilisent les joueurs comme clés.
Exemple :luaCopiersavedScales = { [Player1] = 1.0, -- Player1 a une taille d'origine de 1.0 [Player2] = nil -- Player2 n'est pas réduit }
QCM pour vérifier la compréhension
Sur le flip/flop :
Que fait le script quand un joueur touche la partie pour la première fois ?
a) Il rétrécit le joueur et sauvegarde sa taille d’origine.
b) Il restaure la taille du joueur.
c) Il supprime le joueur.
Que fait le script quand un joueur touche la partie une deuxième fois ?
a) Il rétrécit le joueur.
b) Il restaure la taille d’origine du joueur.
c) Il ne fait rien.
Pourquoi utilise-t-on savedScales[player] = nil quand on restaure la taille ?
a) Pour indiquer que le joueur n’est plus réduit.
b) Pour supprimer le joueur du jeu.
c) Pour accélérer le jeu.
Sur le cooldown :
À quoi sert cooldowns[player] = true ?
a) À bloquer le joueur pendant COOLDOWN secondes.
b) À faire grandir le joueur.
c) À changer la couleur de la partie.
Que se passe-t-il si on supprime if cooldowns[player] then return end ?
a) Le joueur peut déclencher l’effet plusieurs fois par seconde.
b) Le joueur ne peut plus jamais déclencher l’effet.
c) Le jeu plantera.
Sur le nettoyage des tableaux :
Pourquoi nettoyer cooldowns et savedScales quand un joueur quitte ?
a) Pour éviter les fuites de mémoire et les bugs.
b) Pour faire planter le jeu.
c) Pour accélérer le jeu.
Que fait Players.PlayerRemoving:Connect(function(player) ... end) ?
a) Il exécute une fonction quand un joueur quitte le jeu.
b) Il supprime tous les joueurs.
c) Il crée un nouveau joueur.
Sur les conditions :
À quoi sert if originalScale then ... ?
a) À vérifier si le joueur est déjà réduit (et donc doit être restauré).
b) À vérifier si le joueur existe.
c) À changer la couleur du joueur.
2. Ajouter un effet sonore
Objectif : Jouer un son quand le joueur rétrécit ou est restauré.
Indice : Crée un objet Sound dans ReplicatedStorage, puis utilise sound:Play(). Exemple :
local sound = Instance.new("Sound") sound.SoundId = "rbxassetid://123456789" -- Remplace par un vrai ID de son sound.Parent = character.Head sound:Play()
Résumé des concepts appris
Concept
Explication
Exemple dans le script
Variables
Stocker des valeurs (nombres, texte, etc.).
SCALEMINI = 0.3, COOLDOWN = 2
Tableaux associatifs
Stocker des données liées à des clés (ex: joueurs).
Quand un joueur touche une partie (ScalePart), son personnage rétrécit progressivement. Un cooldown (temps d’attente) empêche le joueur de rétrécir trop vite. Le script gère aussi plusieurs joueurs en même temps.
Comprendre le but du script
But :
Créer une partie (ScalePart) qui, quand un joueur la touche, réduit la taille de son personnage.
Limiter la fréquence de rétrécissement avec un cooldown (2 secondes).
Gérer plusieurs joueurs en même temps sans bugs.
Concepts clés :
Constantes : SCALESTEP, SCALEMINI, COOLDOWN.
Tableau associatif : cooldowns pour suivre l’état de chaque joueur.
Événements : Touched pour détecter quand un joueur touche la partie.
Conditions : Vérifier si un joueur peut rétrécir (if cooldowns[player]).
Le script
Voici le script commenté pour comprendre chaque partie :
-- Services et objets nécessaires
local Players = game:GetService("Players") -- Service pour gérer les joueurs
local folder = workspace:WaitForChild("ScaleFolder") -- Dossier contenant la partie
local part = folder:WaitForChild("ScalePart") -- La partie à toucher
-- Variables globales
local SCALESTEP = 0.3 -- Réduction de la taille à chaque toucher
local SCALEMINI = 0.5 -- Taille minimum (le personnage ne peut pas rétrécir en dessous)
local COOLDOWN = 2 -- Temps d'attente (en secondes) avant de pouvoir rétrécir à nouveau
-- Tableau pour gérer les cooldowns des joueurs
-- Format : cooldowns[player] = true si le joueur subi déjà un rétrécissement, nil sinon
local cooldowns = {}
-- Détecter quand un joueur touche la partie
part.Touched:Connect(function(hit)
-- Trouver le personnage du joueur qui a touché la partie
local character = hit:FindFirstAncestorOfClass("Model")
local player = character and Players:GetPlayerFromCharacter(character)
-- Ignorer si ce n'est pas un joueur (ex: un mob, un débris)
if not player then return end
-- VÉRIFIER LE COOLDOWN : Si le joueur est déjà en cooldown, on arrête tout
if cooldowns[player] then return end
-- Trouver l'humanoïde du personnage (pour modifier sa taille)
local humanoid = character:FindFirstChildOfClass("Humanoid")
-- Si l'humanoïde n'existe pas ou si le personnage est déjà à la taille minimum, on arrête
if not humanoid or humanoid.HeadScale.Value <= SCALEMINI then return end
-- ACTIVER LE COOLDOWN pour ce joueur
cooldowns[player] = true
-- Réduire la taille du personnage (corps + tête)
humanoid.BodyHeightScale.Value = math.max(SCALEMINI, humanoid.BodyHeightScale.Value - SCALESTEP)
humanoid.BodyWidthScale.Value = math.max(SCALEMINI, humanoid.BodyWidthScale.Value - SCALESTEP)
humanoid.BodyDepthScale.Value = math.max(SCALEMINI, humanoid.BodyDepthScale.Value - SCALESTEP)
humanoid.HeadScale.Value = math.max(SCALEMINI, humanoid.HeadScale.Value - SCALESTEP) -- Après COOLDOWN secondes, réactiver la possibilité de rétrécir
task.delay(COOLDOWN, function()
cooldowns[player] = nil -- Supprimer le cooldown pour ce joueur
end)
end)
À toi de jouer !
Copie ce script dans un Script dans Roblox Studio (par exemple, dans ServerScriptService).
Crée les éléments nécessaires :
Un dossier ScaleFolder dans Workspace.
Une partie (Part) nommée ScalePart dans ce dossier.
Teste le jeu :
Lance le jeu avec plusieurs joueurs (ou utilise le mode test avec 2 fenêtres).
Touche la ScalePart et observe :
Ton personnage rétrécit.
Tu ne peux pas rétrécir à nouveau avant 2 secondes.
Un autre joueur peut toucher la partie sans être bloqué par ton cooldown.
Explications détaillées
1. Pourquoi un cooldown ?
Problème sans cooldown : Si un joueur ou toutes ses parties touchent le part plusieurs fois en une seconde, son personnage rétrécirait trop vite (voire disparaîtrait !). Exemple : Sans cooldown, un joueur pourrait toucher la part 10 fois en 1 seconde et devenir minuscule instantanément.
Solution avec cooldown : Le script utilise cooldowns[player] = true pour bloquer le rétrécissement pendant 2 secondes (COOLDOWN = 2). Après ce délai, cooldowns[player] = nil permet au joueur de rétrécir à nouveau.
Analogie : Imagine que tu veux boire un verre d’eau, mais tu dois attendre 2 secondes entre chaque gorgée. Le cooldown, c’est comme ce temps d’attente !
2. Pourquoi un tableau cooldowns ?
Gérer plusieurs joueurs : Dans un jeu multijoueur, chaque joueur doit avoir son propre cooldown. Exemple : Si le joueur A touche la partie, seul son cooldown est activé. Le joueur B peut toujours toucher la partie.
Tableau associatif : cooldowns est un tableau où la clé est le player (joueur) et la valeur est true (en cooldown) ou nil (pas en cooldown). Exemple :luaCopiercooldowns = { [Player1] = true, -- Player1 est en cooldown [Player2] = nil -- Player2 peut rétrécir }
Pourquoi pas une variable simple ? Une variable comme isCooldown = true bloquerait tous les joueurs en même temps. Avec un tableau, chaque joueur a son propre état.
3. Autres concepts importants
math.max(SCALEMINI, value) : Garantit que la taille ne descend jamais en dessous de SCALEMINI (0.5). Exemple : Si humanoid.HeadScale.Value = 0.6 et SCALESTEP = 0.3, alors 0.6 - 0.3 = 0.3. Mais math.max(0.5, 0.3) retourne 0.5 (taille minimum).
FindFirstAncestorOfClass("Model") : Permet de remonter dans la hiérarchie de l’objet touché (hit) pour trouver le personnage (qui est un Model).
task.delay(COOLDOWN, function() ... end) : Exécute une fonction après un délai (COOLDOWN secondes). Ici, on réinitialise le cooldown du joueur.
QCM pour vérifier la compréhension
Sur le cooldown :
À quoi sert le cooldown dans ce script ?
a) À empêcher le personnage de rétrécir trop vite.
b) À faire grandir le personnage.
c) À changer la couleur de la partie.
Que se passe-t-il si on supprime if cooldowns[player] then return end ?
a) Le personnage rétrécira une fois, puis plus jamais.
b) Le personnage rétrécira trop vite (plusieurs fois par seconde).
Ce guide complet explique comment intégrer HUSKYLENS 2 à micro:bit ou avec la carte UNIHIKER K10 à l’aide du logiciel MindPlus. Il aborde la configuration matérielle, le chargement des bibliothèques et propose des exemples de programmes pour la reconnaissance faciale, le suivi d’objets, etc.
Des instructions détaillées et des illustrations permettent aux utilisateurs de créer des projets innovants de reconnaissance visuelle.
1. Introduction
1.1 Introduction à Mind+
Mind+ est un logiciel de programmation destiné aux jeunes et basé sur Scratch 3.0. Il prend en charge la programmation graphique et la programmation par code pour diverses plateformes matérielles open source telles qu’Arduino, UNIHIKER K10 et UNIHIKER M10. Les utilisateurs peuvent réaliser des programmes simplement en glissant-déposant des blocs, et peuvent également utiliser des langages de programmation avancés tels que Python, C et C++, permettant ainsi à chacun de découvrir facilement le plaisir de la création.
Le micro:bit est un micro-ordinateur conçu spécifiquement pour l’apprentissage de la programmation chez les enfants et pour l’application des technologies à la résolution de problèmes concrets. HUSKYLENS 2 est compatible avec le micro:bit V2, permettant ainsi le développement de divers projets de reconnaissance visuelle intéressants grâce à la programmation graphique.
Insérez la carte micro:bit dans la carte d’extension compatible FR1616 :
Connectez la carte d’extension à l’ordinateur à l’aide du câble USB-C. Insérez le câble capteur I2C/UART à 4 broches dans l’interface I2C/UART du HUSKYLENS 2, puis connectez l’autre extrémité au port « 5V Huskylens » de la carte d’extension.
Le HUSKYLENS 2 nécessitant une alimentation spécifique, utilisez un câble USB-C supplémentaire pour le connecter à son port d’alimentation, l’autre extrémité étant connectée à un ordinateur ou à une alimentation compatible.
Veuillez vous référer à l’image suivante pour le schéma de câblage :
3. Préparation du logiciel
3.1 Charger la bibliothèque HUSKYLENS 2 dans MindPlus 2.0
Double-cliquez pour ouvrir Mind+. Une fois ouvert, repérez « Extensions » en bas à gauche et cliquez sur « Extensions ».
Lors de la première utilisation, vous devrez télécharger la bibliothèque d’extension du contrôleur principal correspondant.
Recherchez « micro:bit » et cliquez sur l’image de la micro:bit :
Puis cliquez sur User-ext pour charger l’extension logiciel de la carte d’extension :
Charger la bibliothèque drobot_yeezb-unihikerioexpansion-thirdex-V0.0.6.mpext sous 123codage\10 PROJETS ROBOTIQUES\CARTE EXTENSION DF ROBOT :
Cliquez sur l’image de l’extension puis vous validez :
Cliquez sur « Capteur », recherchez « HUSKYLENS 2 » dans la zone de recherche, appuyez sur Enter, trouvez la bibliothèque d’extension « HUSKYLENS 2 », puis cliquez pour charger la bibliothèque d’extension.
Puis demandez le retour :
Vous obtenez les extensions suivantes :
Exemple de projet de reconnaissance faciale
Détection des visages et exportation des données associées
Grâce à la fonction de reconnaissance faciale , lorsqu’un visage apparaît sur l’écran du HUSKYLENS 2, il est détecté et encadré. Vous pouvez ainsi obtenir des données telles que le nombre total de visages détectés. Ces données comprennent l’identifiant du visage, les coordonnées X/Y de son centre, ainsi que sa largeur et sa hauteur.