Catégories
Jeu vidéo ROBLOX ROBLOX-NIVEAU01

Afficher un Message de Chat lors d’une Collision avec une Part

Apprendre à afficher une bulle de chat au-dessus de la tête du joueur quand il touche une Part, avec un cooldown pour éviter le spam. Ce tutoriel explique :

  1. Le service Chat et la fonction Chat:Chat().
  2. Le tableau de cooldown (avec une nouveauté : ici la clé est le personnage, pas le joueur !).
  3. La détection de collision avec Touched.
  4. Au passage : corriger les noms de variables pour qu’ils soient en anglais (bonne pratique de programmeur !).

Introduction : À quoi sert ce script ?

Dans beaucoup de jeux, on veut féliciter le joueur quand il atteint une zone :

  • « Bien joué ! » quand il touche la ligne d’arrivée.
  • « Bravo ! » quand il trouve un secret.

Dans ce script, quand un joueur touche la Part (la ligne d’arrivée par exemple), une bulle verte s’affiche au-dessus de sa tête avec le message « bien jouer ».

Mais il y a un piège ! L’événement Touched se déclenche des dizaines de fois par seconde tant que le joueur touche la Part (une fois par partie du corps qui la touche : pied, jambe, bras…). Sans protection, on verrait des dizaines de bulles de chat en même temps ! C’est pour cela qu’on utilise un cooldown de 10 secondes.

Préparation dans Roblox Studio

  1. Créer la Part :
    • Dans Workspace, ajoute une Part (ex: une ligne d’arrivée plate et large).
    • Positionne-la au sol dans ton niveau.
  2. Ajouter le script DANS la Part (important !) :
    • Clic droit sur la Part → Insert Object → Script.
    • Le script devient enfant de la Part (c’est ce que script.Parent utilise).
  3. Coller le code corrigé ci-dessus dans ce script.
  4. Tester :
    • Lance le jeu et marche sur la Part :
      • Une bulle verte « Bien joué ! » apparaît au-dessus de ta tête.
    • Reste sur la Part ou re-touche-la : rien ne se passe pendant 10 secondes (le cooldown !).
    • Après 10 secondes, retouche-la : la bulle réapparaît !

Script commenté :

-- Récupérer la Part parente du script (la Part qui déclenche le message)
local wellDonePart = script.Parent

-- Récupérer le service Chat pour afficher des bulles de dialogue
local chatService = game:GetService("Chat")

-- Tableau de cooldown : [character] = true si le personnage est en cooldown
local cooldowns = {}

-- Détecter quand quelque chose touche la Part
wellDonePart.Touched:Connect(function(hit)
    -- Récupérer le personnage (Model) qui touche la Part
    local character = hit.Parent
    if not character then return end

    -- VÉRIFIER LE COOLDOWN : si ce personnage a déjà déclenché le message, on arrête
    if cooldowns[character] then return end

    -- Trouver la tête du personnage (là où la bulle de chat apparaît)
    local head = character:FindFirstChild("Head")
    if not head then return end

    -- Afficher une bulle de chat verte au-dessus de la tête avec le message
    chatService:Chat(head, "Bien joué !", Enum.ChatColor.Green)

    -- ACTIVER LE COOLDOWN pour ce personnage pendant 10 secondes
    cooldowns[character] = true
    task.wait(10)   -- Attendre 10 secondes
    cooldowns[character] = false  -- Réautoriser le message
end)

Explications Détaillées

1. script.Parent : le script est DANS la Part !

local wellDonePart = script.Parent
  • Grande nouveauté par rapport aux tutoriels précédents : ici, le script est placé directement dans la Part (dans l’arborescence : Part > Script), pas dans ServerScriptService.
  • script.Parent = l’objet parent du script, c’est-à-dire la Part elle-même !
  • Avantage : le script fonctionne n’importe où où tu copies la Part. Tu peux dupliquer la Part, le script fonctionne tout seul dans chaque copie !

2. Le service Chat et la fonction Chat:Chat()

local chatService = game:GetService("Chat")
chatService:Chat(head, "Bien joué !", Enum.ChatColor.Green)
  • game:GetService("Chat") : service Roblox qui gère les bulles de dialogue.
  • chatService:Chat(...) : affiche une bulle de message au-dessus d’une partie du corps. Elle prend 3 paramètres :
ParamètreValeur iciRôle
1. La partieheadLà où la bulle apparaît (au-dessus de la tête du personnage).
2. Le message"Bien joué !"Le texte affiché dans la bulle.
3. La couleurEnum.ChatColor.GreenLa bulle est verte (il existe aussi Blue, Red, White…).
  • Différence avec le chat normal : Chat:Chat() ne fait qu’afficher une bulle au-dessus du personnage (comme quand un joueur parle dans le jeu). Ce n’est pas un message envoyé dans la fenêtre de chat.

3. Le tableau de cooldown… avec le PERSONNAGE comme clé !

local cooldowns = {}
if cooldowns[character] then return end
cooldowns[character] = true
task.wait(10)
cooldowns[character] = false
  • Rappel des tutoriels précédents : un cooldown, c’est un temps d’attente pour éviter qu’une action se déclenche trop souvent.
  • La nouveauté ici : la clé du tableau n’est ni player, ni userId, mais character (le Model du personnage) !
  • Pourquoi character et pas player ?
    • On n’a pas besoin du joueur : on a déjà son personnage (hit.Parent), et c’est lui qu’on vérifie.
    • Ça économise une étape (pas besoin de Players:GetPlayerFromCharacter).
  • ⚠️ Mais attention, il y a un piège avec ce choix ! Regarde la fin du cooldown :luaCopiercooldowns[character] = false -- Ici on met falseDans les tutoriels précédents, on mettait nil (on supprimait l’entrée). Ici on met false… mais la vérification if cooldowns[character] fonctionne quand même ! Pourquoi ? Parce que la condition vérifie simplement que la valeur n’est ni false ni nil. Les deux solutions marchent :
    • cooldowns[character] = nil → l’entrée n’existe plus (table plus propre).
    • cooldowns[character] = false → l’entrée existe mais vaut false (accepté par le if).
  • Autre piège subtil : quand le joueur meurt et respawn, son personnage est détruit et un nouveau Model est créé. L’ancienne entrée cooldowns[ancienCharacter] reste dans le tableau avec false… mais elle ne gêne pas (elle ne sera plus jamais utilisée). Dans un vrai jeu, on nettoierait avec Players.PlayerRemoving comme dans les tutoriels précédents !

4. La détection de collision avec Touched

wellDonePart.Touched:Connect(function(hit)
    local character = hit.Parent
    if not character then return end
  • hit : la partie du corps (ou objet) qui touche la Part.
  • hit.Parent : le Model du personnage (si un pied touche la Part, hit = le pied, hit.Parent = le personnage entier).
  • if not character then return end : si hit n’a pas de parent (impossible normalement), on arrête.
  • ⚠️ Petit trou dans le filet : ce script vérifie seulement si hit.Parent existe. Une Part libre qui roule sur la ligne d’arrivée a aussi un Parent… mais elle n’a pas de Head, donc la vérification if not head then return end la rejette ! C’est la recherche de la Head qui filtre les vrais joueurs.

5. Pourquoi chercher la Head ?

local head = character:FindFirstChild("Head")
if not head then return end
  • La bulle de chat apparaît au-dessus de la partie qu’on donne en paramètre.
  • On donne la tête pour que la bulle apparaisse au-dessus de la tête du joueur (comme dans le tutoriel des messages cliquables !).
  • Si le personnage n’a pas de tête (ex: un objet qui touche la Part), on arrête : pas de tête, pas de bulle !

QCM : Teste ta compréhension !

Sur le service Chat :

  1. Que fait chatService:Chat(head, "Bien joué !", Enum.ChatColor.Green) ?
    • a) Affiche une bulle verte « Bien joué ! » au-dessus de la tête du personnage.
    • b) Envoie un message dans la fenêtre de chat globale.
    • c) Change la couleur du personnage en vert.
  1. À quoi sert le paramètre Enum.ChatColor.Green ?
    • a) À définir la couleur de la bulle de chat.
    • b) À définir la couleur de la Part.
    • c) À définir la vitesse du personnage.

Sur script.Parent :

  1. Que vaut script.Parent si le script est placé DANS une Part ?
    • a) La Part qui contient le script.
    • b) Le Workspace.
    • c) Le joueur.
  1. Quel est l’avantage de placer le script dans la Part avec script.Parent ?
    • a) On peut dupliquer la Part, et chaque copie fonctionne toute seule.
    • b) Le script va plus vite.
    • c) Le message est plus long.

Sur le cooldown :

  1. Pourquoi un cooldown est-il indispensable ici ?
    • a) L’événement Touched se déclenche des dizaines de fois par seconde, on aurait des dizaines de bulles.
    • b) Pour économiser la batterie.
    • c) Pour changer la couleur du message.
  1. Quelle est la clé du tableau cooldowns dans ce script ?
    • a) Le personnage (character).
    • b) Le pseudo du joueur.
    • c) Le nom de la Part.
  1. Que se passe-t-il pendant les 10 secondes de cooldown si le joueur re-touche la Part ?
    • a) La fonction s’arrête immédiatement à if cooldowns[character] then return end, aucune bulle ne s’affiche.
    • b) La bulle s’affiche quand même.
    • c) Le jeu plante.
  1. Ce script remet le cooldown avec cooldowns[character] = false. Quelle autre écriture était aussi possible (comme dans les tutoriels précédents) ?
    • a) cooldowns[character] = nil (supprimer l’entrée du tableau).
    • b) cooldowns[character] = "stop".
    • c) cooldowns = {} (vider tout le tableau, ce qui supprimerait les cooldowns des AUTRES joueurs !).

Sur la détection de collision :

  1. Que vaut hit quand un joueur touche la Part avec son pied ?
    • a) Le pied (la Part du corps qui touche).
    • b) Le personnage entier.
    • c) Le joueur.
  1. Pourquoi la vérification if not head then return end est-elle utile, en plus de chercher la tête ?
    • a) Elle filtre les objets qui ne sont pas des personnages (une Part qui roule sur la ligne d’arrivée n’a pas de Head).
    • b) Elle accélère le script.
    • c) Elle change la couleur de la bulle.

Idées pour aller plus loin

1. Personnaliser le message avec un attribut (rappel du tutoriel des messages cliquables !)

  • Objectif : Chaque copie de la Part affiche son propre message, sans modifier le script.
  • Comment faire ?
    • Ajoute un attribut Message (type String) sur la Part, puis :luaCopierlocal message = wellDonePart:GetAttribute("Message") or "Bien joué !" chatService:Chat(head, message, Enum.ChatColor.Green)
    • Duplique la Part, change juste l’attribut : "Niveau 1 terminé !", "Zone secrète trouvée !"…

2. Créer un mini-jeu : une course avec score

  • Objectif : La Part donne des points à chaque passage.
  • Comment faire ?luaCopierlocal Players = game:GetService("Players") local player = Players:GetPlayerFromCharacter(character) if player then local leaderstats = player:FindFirstChild("leaderstats") if leaderstats then leaderstats.Score.Value += 1 end end

3. Ajouter un effet visuel et sonore (rappel du tutoriel des particules !)

  • Comment faire ?luaCopierlocal emitter = wellDonePart:FindFirstChildOfClass("ParticleEmitter") local sound = wellDonePart:FindFirstChildOfClass("Sound") if emitter then emitter.Enabled = true end if sound then sound:Play() end task.delay(2, function() if emitter then emitter.Enabled = false end end)

4. Nettoyer le tableau quand le joueur quitte (bonne pratique !)

  • Objectif : Éviter que le tableau cooldowns garde des entrées inutiles.
  • Comment faire ? Comme dans le tutoriel flip/flop, utilise un cooldown basé sur le joueur (player.UserId comme clé, comme le tutoriel des checkpoints) + un nettoyage :luaCopierlocal Players = game:GetService("Players") local player = Players:GetPlayerFromCharacter(character) if not player then return end if cooldowns[player.UserId] then return end cooldowns[player.UserId] = true task.delay(10, function() cooldowns[player.UserId] = nil end) Players.PlayerRemoving:Connect(function(leavingPlayer) cooldowns[leavingPlayer.UserId] = nil end)
    • Bonus : avec task.delay au lieu de task.wait, la fonction Touched ne reste pas bloquée 10 secondes et peut traiter d’autres joueurs !

Résumé des concepts clés

ConceptDescriptionExemple
script.ParentL’objet qui contient le script (ici, la Part).local wellDonePart = script.Parent
game:GetService("Chat")Service pour afficher des bulles de dialogue.chatService:Chat(head, message, color)
Chat:Chat()Affiche une bulle au-dessus d’une partie, avec un message et une couleur.Enum.ChatColor.Green
TouchedÉvénement déclenché à chaque contact avec la Part (très fréquent !).wellDonePart.Touched:Connect(...)
hit.ParentLe personnage (Model) qui touche la Part.local character = hit.Parent
FindFirstChild("Head")Cherche la tête (et filtre les non-personnages).if not head then return end
Tableau de cooldown[character] = true pendant 10 secondes pour bloquer le spam.if cooldowns[character] then return end
task.wait(10)Attend 10 secondes avant de réautoriser le message.À la fin du cooldown