Objectif : Créer des interfaces utilisateur magnifiques et fonctionnelles ! Menus, barres de vie, inventaires... Donne à ton jeu un look professionnel.
Ce que le joueur voit et utilise
Une bonne interface (GUI = Graphical User Interface) fait la différence entre un jeu amateur et un jeu pro. Barres de vie, menus, notifications... C'est le visage de ton jeu !
Une bonne GUI ne commence pas par des propriétés techniques, mais par une intention claire : quelle information le joueur doit voir, quelle action il doit faire, en combien de secondes il comprend l'écran.
Règle pratique : chaque élément de l'UI doit avoir un rôle unique (informer, guider, agir). Si un élément n'a pas de rôle précis, supprime-le. Une interface simple et claire est plus pro qu'une interface surchargée.
1) Lisible sur différentes résolutions.
2) Boutons assez grands et cohérents.
3) Hiérarchie visuelle claire (titre, action principale,
informations secondaires).
4) Retour utilisateur visible (hover, clic, confirmation).
Une bonne GUI dépend du contexte : pendant l'action, privilégie des infos courtes et visibles; dans les menus, privilégie clarté et navigation. Le joueur doit toujours savoir où regarder et quoi faire.
Pense "charge cognitive" : plus le jeu est intense, plus l'interface doit être simple. Trop d'éléments à l'écran peut ruiner la lisibilité et l'immersion.
Définition : Hiérarchie d'objets UI (ScreenGui, Frame, éléments enfants).
Pourquoi : Une base propre simplifie tout le reste.
Quand l'utiliser : Création de menu, HUD, boutique, inventaire.
Anti-pattern : Hiérarchie désordonnée et noms d'objets imprécis.
Exercice guidé : Monte une arborescence UI claire pour un mini menu.
Résumé : Une bonne structure UI = moins de bugs et plus de vitesse.
Définition : Position/taille avec scale + offset pour s'adapter aux écrans.
Pourquoi : Garantir une UI responsive sur mobile et PC.
Quand l'utiliser : Placement de tous les composants visibles.
Anti-pattern : Utiliser uniquement des offsets fixes.
Exercice guidé : Centre un panneau et vérifie son rendu sur 2 résolutions.
Résumé : UDim2 bien maîtrisé = interface robuste multi-écrans.
Définition : Relier interactions utilisateur et comportement UI.
Pourquoi : Une interface utile doit réagir aux actions du joueur.
Quand l'utiliser : Boutons, transitions d'écran, messages dynamiques.
Anti-pattern : Logique métier sensible directement dans l'UI locale.
Exercice guidé : Crée un bouton qui ouvre/ferme un panneau avec état persistant.
Résumé : L'UI scriptée doit rester claire, rapide et prédictible.
Définition : Composants qui organisent automatiquement les éléments.
Pourquoi : Éviter le placement manuel fragile.
Quand l'utiliser : Listes dynamiques, inventaires, galeries, tableaux.
Anti-pattern : Positionner chaque élément à la main dans une liste variable.
Exercice guidé : Génère une liste d'objets avec UIListLayout et padding cohérent.
Résumé : Les layouts automatiques rendent les interfaces scalables.
Les interfaces Roblox suivent une hiérarchie précise. Tout commence par un ScreenGui qui contient tes éléments.
Le conteneur principal. Tout ce qui est dedans s'affiche à l'écran.
IgnoreGuiInset = true pour utiliser tout l'écran.
Rectangle conteneur. Idéal pour grouper des éléments.
Peut avoir une couleur de fond, bordure, etc.
Affiche du texte non-cliquable.
Pour les scores, titres, descriptions.
Bouton cliquable avec du texte.
Événement .MouseButton1Click
En Roblox, on positionne les éléments avec UDim2, qui combine des valeurs en Scale (%) et Offset (pixels).
Syntaxe UDim2
-- UDim2.new(ScaleX, OffsetX, ScaleY, OffsetY)
-- Position au centre de l'écran
frame.Position = UDim2.new(0.5, 0, 0.5, 0)
-- Taille : 50% largeur, 100 pixels de haut
frame.Size = UDim2.new(0.5, 0, 0, 100)
-- Combo : 30% + 20 pixels
frame.Size = UDim2.new(0.3, 20, 0.2, 10)
Pourcentage de l'écran
0.5 = 50%
S'adapte à la taille d'écran
Valeur fixe en pixels
100 = 100px
Toujours la même taille
Par défaut, la position est calculée depuis le coin supérieur gauche. AnchorPoint change le point de référence.
-- Pour centrer parfaitement un élément :
frame.AnchorPoint = Vector2.new(0.5, 0.5) -- Centre
frame.Position = UDim2.new(0.5, 0, 0.5, 0) -- 50%, 50%
-- Résultat : L'élément est parfaitement centré !
AnchorPoint (0, 0) = Coin supérieur gauche
(défaut)
AnchorPoint (0.5, 0.5) = Centre
AnchorPoint (1, 1) = Coin inférieur droit
Les scripts GUI vont dans un LocalScript à l'intérieur du ScreenGui ou de l'élément. Rappelle-toi : les GUI sont côté Client !
Bouton simple
local bouton = script.Parent
bouton.MouseButton1Click:Connect(function()
print("Bouton cliqué !")
bouton.Text = "Cliqué ?"
end)
-- Effet au survol
bouton.MouseEnter:Connect(function()
bouton.BackgroundColor3 = Color3.fromRGB(100, 100, 255)
end)
bouton.MouseLeave:Connect(function()
bouton.BackgroundColor3 = Color3.fromRGB(80, 80, 200)
end)
local scoreLabel = script.Parent.ScoreLabel
local score = 0
-- Met à jour l'affichage
local function updateScore()
scoreLabel.Text = "Score: " .. score
end
-- Quand le joueur gagne des points
local function addPoints(points)
score = score + points
updateScore()
end
addPoints(100) -- Score: 100
local menu = script.Parent.Menu
local openButton = script.Parent.OpenButton
local closeButton = menu.CloseButton
openButton.MouseButton1Click:Connect(function()
menu.Visible = true
end)
closeButton.MouseButton1Click:Connect(function()
menu.Visible = false
end)
Plutôt que de positionner chaque élément manuellement, utilise des Layouts pour organiser automatiquement tes éléments.
Empile les éléments verticalement ou horizontalement.
Parfait pour les menus et listes.
Grille automatique avec cellules de taille fixe.
Parfait pour les inventaires.
Ajoute des marges intérieures.
Évite que le contenu touche les bords.
Garde un ratio largeur/hauteur fixe.
Parfait pour les images carrées.
Exemple : Menu avec UIListLayout
-- Structure :
-- Frame "Menu"
-- UIListLayout (FillDirection = Vertical, Padding = 10)
-- TextButton "Jouer"
-- TextButton "Options"
-- TextButton "Quitter"
-- Les boutons s'empilent automatiquement !
5 questions pour valider tes acquis
Crée l'interface visuelle qui affichera tes niveaux d'Oxygène et d'Énergie. On va la préparer pour qu'elle réagisse automatiquement !
Modules 1 à 7 complétés (GUI, ScreenGui)
Dans StarterGui, crée un
ScreenGui nommé "HUD".
Dedans, ajoute une Frame nommée "BarresContainer"
positionnée en bas à gauche.
Dans "BarresContainer", crée 2 Frames pour les jauges :
Ajoute un LocalScript dans le ScreenGui. Il doit écouter les attributs du joueur et mettre à jour les barres.
player,
gui, barreOxy,
barreEnerg
updateHUD() qui :
AttributeChanged à ta fonction
updateHUD
Lance le jeu. Dans l'Explorer, sélectionne ton Joueur (Players > Toi). Dans les Propriétés, ajoute un Attribut "Oxygene" (Number) et change sa valeur. La barre bouge !
Prochaine étape ? Module 9 : Collecte & Sauvegarde
Transforme ta station en une expérience professionnelle ! Anime les barres de ressources, les portes, et les alertes avec TweenService pour des transitions ultra-smooth.
TweenService permet d'animer n'importe quelle propriété d'un objet de façon fluide. Voici les concepts clés :
-- Syntaxe de base
local TweenService = game:GetService("TweenService")
local info = TweenInfo.new(
0.5, -- Durée en secondes
Enum.EasingStyle.Quad, -- Style de courbe
Enum.EasingDirection.Out -- Direction
)
local tween = TweenService:Create(
objet, -- L'objet à animer
info, -- Configuration
{Size = UDim2.new(0.5, 0, 1, 0)} -- Propriétés cibles
)
tween:Play() -- Lance l'animation !
Modifie le LocalScript HUD_Client du Module 7 pour
utiliser TweenService au lieu de changer la taille directement :
-- HUD_Client.lua - Version Animée !
local TweenService = game:GetService("TweenService")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local miseAJourHUD = ReplicatedStorage:WaitForChild("MiseAJourHUD")
local hud = script.Parent
local barreEnergie = hud:WaitForChild("BarreEnergie")
local remplissageEnergie = barreEnergie:WaitForChild("Remplissage")
local labelEnergie = barreEnergie:WaitForChild("Label")
-- Configuration des animations
local tweenInfo = TweenInfo.new(
0.3, -- 0.3 seconde
Enum.EasingStyle.Quad, -- Courbe douce
Enum.EasingDirection.Out -- Décélère à la fin
)
local tweenInfoCouleur = TweenInfo.new(
0.5, -- Plus lent pour la couleur
Enum.EasingStyle.Sine,
Enum.EasingDirection.InOut
)
-- FONCTION : Animer la barre d'énergie
local function animerBarreEnergie(pourcent)
-- Calculer la nouvelle taille
local nouvelleTaille = UDim2.new(pourcent, 0, 1, 0)
-- Créer et jouer le tween de taille
local tweenTaille = TweenService:Create(
remplissageEnergie,
tweenInfo,
{Size = nouvelleTaille}
)
tweenTaille:Play()
-- Déterminer la couleur selon le niveau
local nouvelleCouleur
if pourcent > 0.5 then
nouvelleCouleur = Color3.fromRGB(0, 255, 127) -- Vert
elseif pourcent > 0.25 then
nouvelleCouleur = Color3.fromRGB(255, 165, 0) -- Orange
else
nouvelleCouleur = Color3.fromRGB(255, 50, 50) -- Rouge
end
-- Animer la couleur aussi !
local tweenCouleur = TweenService:Create(
remplissageEnergie,
tweenInfoCouleur,
{BackgroundColor3 = nouvelleCouleur}
)
tweenCouleur:Play()
end
-- Recevoir les données du serveur
miseAJourHUD.OnClientEvent:Connect(function(ressources)
local pct = ressources.energie / ressources.energieMax
animerBarreEnergie(pct)
labelEnergie.Text = "⚡ " .. math.floor(ressources.energie)
end)
Remplace les boucles for du script de porte du Module 6
par des Tweens pour une animation pro :
-- Dans ControleurPorte.lua - Remplace les boucles par :
local TweenService = game:GetService("TweenService")
local tweenInfoPorte = TweenInfo.new(
0.8, -- Durée
Enum.EasingStyle.Back, -- Effet "rebond"
Enum.EasingDirection.Out
)
-- FONCTION : Ouvrir avec Tween
local function ouvrirPorteAnimee()
local posGaucheOuverte = posGaucheFermee - Vector3.new(DISTANCE_OUVERTURE, 0, 0)
local posDroiteOuverte = posDroiteFermee + Vector3.new(DISTANCE_OUVERTURE, 0, 0)
local tweenGauche = TweenService:Create(porteGauche, tweenInfoPorte, {Position = posGaucheOuverte})
local tweenDroite = TweenService:Create(porteDroite, tweenInfoPorte, {Position = posDroiteOuverte})
tweenGauche:Play()
tweenDroite:Play()
-- Attendre la fin de l'animation
tweenGauche.Completed:Wait()
end
Ajoute une alerte visuelle quand l'énergie est critique. Crée un Frame rouge qui pulse :
-- Dans HUD_Client.lua - Ajoute après les autres variables
local alerteFrame = hud:WaitForChild("AlerteEnergie")
local alerteActive = false
-- Configuration du pulse
local tweenPulseIn = TweenInfo.new(
0.3,
Enum.EasingStyle.Sine,
Enum.EasingDirection.InOut,
-1, -- Répète infiniment
true -- Reverse (fait l'aller-retour)
)
-- FONCTION : Activer l'alerte
local function activerAlerte()
if alerteActive then return end
alerteActive = true
alerteFrame.Visible = true
local tween = TweenService:Create(alerteFrame, tweenPulseIn, {
BackgroundTransparency = 0.3
})
tween:Play()
end
-- FONCTION : Désactiver l'alerte
local function desactiverAlerte()
alerteActive = false
alerteFrame.Visible = false
end
-- Dans la fonction de mise à jour, ajoute :
if pct < 0.2 then
activerAlerte()
else
desactiverAlerte()
end
Lance le jeu avec F5 et observe :
TweenService:Create() → Créer une animationTweenInfo → Configurer durée, style, répétitionEasingStyle → Quad, Sine, Back, Bounce, Elastic...Completed:Wait() → Attendre la fin d'un tween
Tes animations donnent à ta station un feeling AAA ! → Module 9 : Ambiance sonore et effets visuels