Créer une interface utilisateur interactive

*Ce contenu est traduit en utilisant l'IA (Beta) et peut contenir des erreurs. Pour consulter cette page en anglais, clique ici.

Un HUD (Heads-Up Display) dans votre jeu affiche généralement des éléments d'interface utilisateur non interactifs tels que le compteur de santé démontré dans Créer des compteurs HUD. De plus, presque tous les jeux nécessitent une interface utilisateur interactive comme des boutons qui réagissent à l'activation du joueur, s'animent lorsqu'ils sont activés, font apparaître/disparaître des menus avec d'autres contrôles interactifs, etc.

Vue en jeu montrant un bouton de paramètres et un menu de paramètres avec des curseurs de volume.

En utilisant UI Fundamentals - HUD Meter comme point de départ et UI Fundamentals - Interactivity comme référence terminée, ce tutoriel démontre :

  • Comment positionner un bouton de paramètres le long du bord supérieur de l'écran.
  • Conception d'un menu de paramètres contenant des curseurs interactifs et glissables.
  • Utilisation d'un ModuleScripts pour former des modules "contrôleur" pour un contrôle extensible des objets UI avec des déclarations d'état.
  • Comment connecter des boutons à l'activation du joueur pour faire apparaître/disparaître le menu de paramètres.
  • Comment connecter des curseurs UI glissables pour ajuster séparément le volume des effets sonores et de l'ambiance de fond.

Activer l'émulateur de périphérique

Comme noté dans Créer des compteurs HUD, les téléphones et les tablettes ont le moins d'espace d'écran, il est donc important que vos éléments d'interface utilisateur s'adaptent aux écrans plus petits et qu'ils soient clairement visibles pour les joueurs. Si vous ne l'avez pas encore fait, activez l'émulateur de périphérique dans Studio :

  1. Ouvrez le modèle UI Fundamentals - HUD Meter dans Studio.

  2. Dans le menu Test de Studio, activez Émulateur de périphérique.

  3. Dans la barre directement au-dessus de la vue principale, sélectionnez une émulation de téléphone telle que iPhone X ou Samsung Galaxy A51. Ensuite, définissez la taille de la vue sur Ajuster à la fenêtre pour utiliser l'espace maximum dans Studio.

    Options de paramètres de l'émulateur de périphérique indiquées en haut de la fenêtre de visualisation.

Créer le bouton de paramètres

GuiButtons sont des éléments d'interface utilisateur interactifs avec des fonctionnalités intégrées telles que l'événement multi-plateforme Activated qui se déclenche lorsque le bouton est cliqué ou touché. La classe GuiButton s'étend à deux variations, TextButton et ImageButton, et ce tutoriel utilise un ImageButton en forme de "roue dentée" pour ouvrir ou fermer le menu de paramètres.

Composant Roblox utilisé pour le bouton de paramètres.

Pour construire le bouton de paramètres :

  1. Dans la fenêtre Explorer, localisez HUDContainer à l'intérieur de StarterGui.

    Fenêtre Explorer montrant le HUDContainer sélectionné.
  2. Insérez un ImageButton dans HUDContainer et renommez-le en SettingsButton.

    Fenêtre Explorer montrant le nouvel ImageButton inséré et renommé en SettingsButton. Nouveau ImageButton dans la vue.
  3. Avec le nouveau bouton sélectionné, définissez les éléments suivants dans la fenêtre Propriétés :

    • AnchorPoint = 0.5, 0.25 (centre horizontal et quart supérieur vertical)
    • BackgroundTransparency = 1 (entièrement transparent)
    • Position = 0.5, 0, 0, 0 (positionnement centre-haut)
    • Size = 0.1, 0, 0.1, 0 (10% de la hauteur de l'écran une fois le rapport d'aspect contraint)
    • Image = rbxassetid://104919049969988 (ID d'actif du symbole "roue dentée")
  4. Insérez un UIAspectRatioConstraint dans le bouton avec les propriétés par défaut (rapport 1:1 largeur/hauteur).

    Fenêtre Explorer montrant un nouveau UIAspectRatioConstraint inséré dans le bouton SettingsButton.
  5. Pour limiter la hauteur maximale en pixels du bouton, insérez un UISizeConstraint et définissez son MaxSize sur inf, 44.

    Fenêtre Explorer montrant un nouveau UISizeConstraint inséré dans le bouton SettingsButton.
    Fenêtre Propriétés montrant les valeurs attendues pour le nouveau UISizeConstraint.
    Bouton de paramètres finalisé au centre supérieur de l'écran.

Créer le menu de paramètres

Le nouveau bouton de paramètres sera scripté pour ouvrir et fermer un menu de paramètres, donnant aux joueurs un accès à la demande aux paramètres ou à d'autres informations. Dans ce tutoriel, le menu contiendra des curseurs interactifs pour ajuster indépendamment les niveaux de volume de l'audio de fond et des effets sonores.

Composants de base utilisés pour le menu de paramètres.

Créer le cadre parent

Comme noté dans Créer des compteurs HUD, un Frame sert de conteneur pour d'autres objets UI. L'ensemble du menu de paramètres sera construit avec un seul cadre parent, ce qui le rend simple à gérer en tant qu'objet avec état qui réagit différemment à l'entrée en fonction de l'état actuel.

  1. Insérez un Frame dans HUDContainer et renommez-le en SettingsMenu.

    Fenêtre Explorer montrant un nouveau cadre inséré et renommé en SettingsMenu.
  2. Avec SettingsMenu sélectionné, définissez les propriétés suivantes :

    Cadre repositionné, redimensionné et stylisé avec un fond bleu marine transparent.
  3. Insérez un UIAspectRatioConstraint dans SettingsMenu et définissez sa propriété AspectRatio sur 2.5. (2.5:1 largeur/hauteur).

    Fenêtre Explorer montrant un nouveau UISizeConstraint inséré dans le cadre SettingsMenu.
    Fenêtre Propriétés montrant les valeurs attendues pour le nouveau UISizeConstraint.
  4. Insérez un modificateur UICorner dans SettingsMenu et définissez sa propriété CornerRadius sur 0.1, 0.

    Fenêtre Explorer montrant un nouveau UICorner inséré dans le cadre SettingsMenu.
    Fenêtre Propriétés montrant les valeurs attendues pour le nouveau modificateur UICorner.
  5. Pour contraindre la largeur et la hauteur en pixels de SettingsMenu, insérez un UISizeConstraint. Définissez son MaxSize sur 800, inf et son MinSize sur 350, 0.

    Fenêtre Explorer montrant un nouveau UISizeConstraint inséré dans le cadre SettingsMenu.
    Fenêtre Propriétés montrant les valeurs attendues pour le nouveau UISizeConstraint.
    Cadre stylisé avec des coins arrondis.

Construire un curseur

Pour permettre aux joueurs d'ajuster les niveaux de volume, le menu de paramètres contiendra deux widgets de curseur glissables alimentés par UIDragDetector, un objet pratique qui facilite l'interaction avec des éléments d'interface utilisateur 2D.


Pour créer un conteneur parent pour le premier curseur :

  1. Insérez un nouveau Frame dans le conteneur SettingsMenu et renommez-le en EffectsVolumeSlider.

    Fenêtre Explorer montrant un nouveau cadre inséré dans le cadre SettingsMenu, renommé en EffectsVolumeSlider.
  2. Avec le cadre EffectsVolumeSlider sélectionné, définissez les propriétés suivantes :

    • AnchorPoint = 0.5 (ancre centrale)

    • BackgroundTransparency = 1 (entièrement transparent)

    • Position = 0.5, 0, 0.35, 0 (centre horizontal et 35% du haut du conteneur)

    • Size = 0.8, 0, 0.1, 0 (80% de la largeur du conteneur et 10% de sa hauteur)

      Cadre vide inséré pour contenir les éléments du curseur.
  3. Insérez un nouveau UIListLayout dans EffectsVolumeSlider. Ce modificateur de mise en page est un moyen puissant d'auto-organiser les GuiObjects frères et sœurs en lignes horizontales ou colonnes verticales dans leur conteneur parent, y compris la capacité d'appliquer des concepts de flex.

    Fenêtre Explorer montrant un nouveau UIListLayout inséré dans le cadre EffectsVolumeSlider.
  4. Définissez les propriétés suivantes pour le nouveau UIListLayout :

    • Padding = 0.06, 0 (6% d'espacement entre les éléments de la liste)
    • FillDirection = Horizontal (disposition des éléments de gauche à droite)
    • HorizontalFlex = Fill (redimensionner les éléments horizontalement pour remplir l'ensemble du conteneur parent, en remplaçant leur largeur définie)
    • VerticalAlignment = Center (aligner les éléments le long de leur centre vertical)

Icône du curseur

Une simple icône comprenant une note audio et un symbole de "burst" aide les joueurs à identifier l'objectif du curseur lorsqu'ils ouvrent le menu de paramètres.

Icône indiquant l'objectif du curseur dans le menu de paramètres.
  1. Insérez un ImageLabel dans le cadre EffectsVolumeSlider et renommez-le en Icon. Cette icône aidera les joueurs à comprendre quel aspect du jeu le curseur contrôle.

    Fenêtre Explorer montrant un ImageLabel inséré dans le cadre EffectsVolumeSlider.
  2. Avec Icon sélectionné, définissez les propriétés suivantes :

    • BackgroundTransparency = 1 (entièrement transparent)
    • Size = 2.5, 0, 2.5, 0 (250% de la hauteur du cadre parent une fois le rapport d'aspect contraint)
    • Image = rbxassetid://90019827067389 (ID d'actif de la note audio et du symbole "burst")
  3. Insérez un UIAspectRatioConstraint dans Icon et laissez ses propriétés par défaut (1:1 largeur/hauteur).

    Fenêtre Explorer montrant un UIAspectRatioConstraint inséré dans l'ImageLabel. Icône finalisée dans le menu de paramètres.

Cadre de plage

Directement à droite de l'icône, la partie interactive du curseur doit être contenue dans un autre Frame.

Taille et position cibles de la partie interactive du curseur.
  1. Insérez un nouveau Frame dans le cadre EffectsVolumeSlider et renommez-le en SliderFrame. Notez qu'il doit être un frère direct du modificateur de mise en page UIListLayout.

    Fenêtre Explorer montrant un cadre enfant inséré dans le cadre EffectsVolumeSlider.
  2. Avec SliderFrame sélectionné, définissez les propriétés suivantes :

  3. Insérez les modificateurs suivants dans SliderFrame :

    Cadre du curseur positionné à droite de l'icône.

Poignée interactive

Avec le conteneur de curseur construit, vous pouvez maintenant créer une poignée glissable pour que les joueurs interagissent pendant le jeu.

Poignée de curseur interactive positionnée dans le cadre de plage.
  1. Insérez un nouveau Frame dans le conteneur SliderFrame et renommez-le en Handle.

    Fenêtre Explorer montrant un cadre enfant inséré dans le cadre SliderFrame et renommé en Handle.
  2. Avec Handle sélectionné, définissez les propriétés suivantes :

    • AnchorPoint = 0.5 (ancre centrale)
    • Position = 0.5, 0, 0.5, 0 (centre horizontal et vertical du cadre parent)
    • Size = 1.2, 0, 1.2, 0 (120% de la hauteur du cadre parent une fois le rapport d'aspect contraint)
    • ZIndex = 3 (couche de la poignée visuellement devant les autres éléments du curseur)
  3. Insérez les modificateurs suivants dans Handle :

  4. Insérez un objet UIDragDetector dans Handle. Cet objet pratique facilite et encourage l'interaction avec des éléments d'interface utilisateur 2D.

    Fenêtre Explorer montrant un UIDragDetector inséré dans le cadre Handle.
  5. Définissez les propriétés suivantes pour le nouveau UIDragDetector :

  6. Pour s'assurer que la plage de glissement linéaire de la poignée est limitée à son conteneur, liez sa propriété BoundingUI au conteneur SliderFrame :

    1. Sélectionnez le UIDragDetector.
    2. Cliquez sur sa propriété BoundingUI dans la fenêtre Propriétés.
    3. De retour dans la fenêtre Explorer, cliquez sur le parent SliderFrame de la poignée.
    Diagramme montrant le processus de liaison de la propriété BoundingUI du détecteur au conteneur SliderFrame.

    La liaison de la propriété BoundingUI reflète maintenant le conteneur SliderFrame :

    Fenêtre Propriétés montrant la propriété BoundingUI du détecteur liée au conteneur SliderFrame.

Si vous testez le jeu maintenant, vous pourrez glisser la poignée de gauche à droite dans son conteneur parent :

Remplissage intérieur

Pour indiquer plus clairement que le curseur contrôle une plage de 0% à 100%, vous pouvez ajouter un remplissage intérieur sur le côté gauche du conteneur qui se synchronisera avec la position variable de la poignée.

Partie de remplissage intérieur du curseur insérée dans SliderFrame.
  1. Insérez un nouveau Frame dans le conteneur SliderFrame et renommez-le en InnerFill.

    Fenêtre Explorer montrant un cadre enfant inséré dans le cadre SliderFrame et renommé en InnerFill.
  2. Définissez les propriétés suivantes pour le cadre InnerFill :

    • AnchorPoint = 0, 0.5 (bord gauche et centre vertical)
    • BackgroundColor3 = [0, 150, 255] (bleu correspondant à la poignée du curseur)
    • BackgroundTransparency = 0.35 (65% opaque)
    • Position = 0, 0, 0.5, 0
    • Size = 0.5, 0, 1, 0 (50% de largeur et 100% de hauteur du cadre parent)
    • ZIndex = 2 (couche visuellement devant le remplissage/contour du cadre parent)
  3. Pour correspondre à la forme "pilule" du conteneur parent SliderFrame, insérez un modificateur UICorner et définissez sa propriété CornerRadius sur 0.5, 0.

    Fenêtre Explorer montrant un modificateur UICorner inséré dans le cadre InnerFill.
    Fenêtre Propriétés montrant les valeurs attendues pour le nouveau UICorner.
    Cadre InnerFill stylisé avec un fond bleu et des coins arrondis.

Dupliquer le curseur

Avec le premier curseur construit, vous pouvez facilement le dupliquer et modifier certains aspects visuels pour indiquer un autre objectif, dans ce cas le niveau de volume de l'audio de fond symbolisé par une icône de notes musicales.

Position cible du curseur audio de fond.
  1. Sélectionnez l'objet EffectsVolumeSlider complété.

    Fenêtre Explorer montrant l'EffectsVolumeSlider complété sélectionné.
  2. Dupliquez-le (CtrlD ou D) puis renommez le duplicata en BackgroundVolumeSlider.

    Fenêtre Explorer montrant le curseur dupliqué renommé en BackgroundVolumeSlider.
  3. Changez la Position du duplicata en 0.5, 0, 0.7, 0 pour le déplacer en dessous du premier curseur.

    BackgroundVolumeSlider positionné en dessous de EffectsVolumeSlider.
  4. Développez la branche de premier niveau de BackgroundVolumeSlider, sélectionnez l'étiquette d'image Icon, et changez sa propriété Image en rbxassetid://101125859760167 (ID d'actif du symbole avec des notes musicales).

    Fenêtre Explorer montrant l'étiquette Icon dans BackgroundVolumeSlider.
    Fenêtre Propriétés montrant les valeurs attendues pour l'étiquette Icon.
    BackgroundVolumeSlider avec l'image d'icône modifiée.
  5. Développez la branche SliderFrameHandle, sélectionnez le modificateur UIStroke à l'intérieur, et définissez sa propriété Color sur [255, 0, 125] (magenta).

    Fenêtre Explorer montrant le modificateur UIStroke à l'intérieur de la poignée de BackgroundVolumeSlider.
    Fenêtre Propriétés montrant les valeurs attendues pour le modificateur UIStroke.
    BackgroundVolumeSlider avec l'image d'icône modifiée.
  6. Sélectionnez le cadre InnerFill dans SliderFrame et changez sa propriété BackgroundColor3 en la même couleur magenta ([255, 0, 125]).

    Fenêtre Explorer montrant le cadre InnerFill dans le conteneur SliderFrame de BackgroundVolumeSlider.
    Fenêtre Propriétés montrant les valeurs attendues pour le cadre InnerFill.
    BackgroundVolumeSlider avec la couleur InnerFill modifiée.

Créer le bouton de fermeture

Le dernier élément du menu de paramètres est un bouton de fermeture qui fournit aux joueurs une entrée supplémentaire pour fermer le menu (le SettingsButton au centre supérieur servira le même objectif).

Menu de paramètres avec le bouton de fermeture indiqué dans le coin supérieur droit.
  1. Insérez un nouveau ImageButton dans le conteneur SettingsMenu et renommez-le en CloseButton.

    Fenêtre Explorer montrant un nouveau ImageButton inséré dans SettingsMenu et renommé en CloseButton. ImageButton vide positionné dans le coin supérieur gauche du menu de paramètres.
  2. Avec CloseButton sélectionné, définissez les propriétés suivantes :

    • AnchorPoint = 1, 0 (coin supérieur droit)
    • BackgroundTransparency = 1 (entièrement transparent)
    • Position = 1, -10, 0, 10 (10 pixels d'inset du coin supérieur droit)
    • Size = 0.15, 0, 0.15, 0 (15% de la hauteur du cadre une fois le rapport d'aspect contraint)
    • Image = rbxassetid://5577404210 (ID d'actif du symbole de bouton de fermeture)
    • ImageTransparency = 0.25 (75% opaque)
  3. Insérez un UIAspectRatioConstraint dans le bouton avec les propriétés par défaut (1:1 largeur/hauteur).

    Fenêtre Explorer montrant un UIAspectRatioConstraint inséré dans le bouton CloseButton. Bouton de fermeture finalisé dans le coin supérieur droit du menu de paramètres.

Créer les modules de contrôle

Une configuration de module de contrôle extensible rend la gestion de l'interface utilisateur interactive plus rationalisée que des scripts individuels placés dans chaque objet. ModuleScripts facilitent cette fonctionnalité extensible en vous permettant de réutiliser du code entre des scripts de différents côtés de la frontière client-serveur ou du même côté de la frontière.

Contrôleur d'objet avec état

Le module de contrôleur d'objet avec état suivant vous permet d'attacher un comportement aux objets UI tels que SettingsButton et SettingsMenu, et de basculer facilement entre divers états. Pour créer le module :

  1. Insérez un ModuleScript dans le conteneur ReplicatedStorage et renommez-le en StatefulObjectController.

    Fenêtre Explorer montrant le module StatefulObjectController à l'intérieur du conteneur ReplicatedStorage.
  2. Collez le code suivant à l'intérieur du module :

    StatefulObjectController
    local TweenService = game:GetService("TweenService")
    local StatefulObjectController = {}
    StatefulObjectController.__index = StatefulObjectController
    export type StateName = string
    export type State = {
    transition: TweenInfo,
    properties: { [string]: any },
    }
    function StatefulObjectController.hydrate(props: {
    object: Instance,
    states: { [StateName]: State },
    initialStateName: StateName
    })
    local object, states, initialStateName = props.object, props.states, props.initialStateName
    local self = setmetatable({
    states = states,
    currentStateName = initialStateName,
    tweens = {},
    }, StatefulObjectController)
    -- Créer des tweens pour réutilisation afin d'éviter de créer de nouveaux tweens chaque fois que l'état change
    for stateName, state in states do
    self.tweens[stateName] = TweenService:Create(object, state.transition, state.properties)
    end
    self:setState(self.currentStateName)
    return self
    end
    function StatefulObjectController:setState(stateName: StateName)
    local stateTween: Tween = self.tweens[stateName]
    if not stateTween then
    warn(string.format("Tentative de définir %s à un état inconnu '%s'", self.object:GetFullName(), stateName))
    return
    end
    self.currentStateName = stateName
    -- Assurez-vous que d'autres tweens ne sont pas en conflit
    for _, tween in self.tweens do
    tween:Cancel()
    end
    stateTween:Play()
    end
    return StatefulObjectController
    LignesBut
    610Définit et exporte les types Luau pour améliorer l'autocomplétion et le linting lors de l'utilisation de ce module.
    1233Fonction utilisée pour initialiser et attacher un comportement à un objet UI avec état, acceptant un GuiObject comme object, une table d'états et leurs données respectives TweenInfo, et un nom d'état initial. À l'intérieur de cette fonction, les lignes 2628 construisent des Tweens pour chaque état, et la ligne 30 appelle la fonction setState() du module pour définir l'objet à l'état initial.
    3550Fonction utilisée pour définir/changer l'état d'un objet avec état. La ligne 42 définit le currentStateName de l'objet à l'état défini, les lignes 4547 annulent tous les tweens en cours pour éviter les conflits, et la ligne 49 exécute le(s) tween(s) de l'état.

Contrôleur de curseur

Un module supplémentaire initialise et contrôle les deux curseurs de volume. Il vous permet également de connecter une fonction de rappel à chaque curseur afin de détecter l'interaction du joueur avec le curseur et d'appliquer les changements souhaités dans le jeu.

  1. Insérez un ModuleScript dans le conteneur ReplicatedStorage et renommez-le en SliderController.

    Fenêtre Explorer montrant le module SliderController à l'intérieur du conteneur ReplicatedStorage.
  2. Collez le code suivant à l'intérieur du module :

    SliderController
    local SliderController = {}
    SliderController.__index = SliderController
    export type Value = number
    export type OnChanged = (Value) -> ()
    function SliderController.hydrate(props: {
    object: Instance,
    onChanged: OnChanged,
    initialValue: Value?
    })
    local object, onChanged, initialValue = props.object, props.onChanged, props.initialValue
    local handle = object:FindFirstChild("Handle", true)
    if not handle then
    warn(string.format("Tentative d'hydrater le curseur %s mais impossible de trouver Handle", object:GetFullName()))
    end
    local innerFill = object:FindFirstChild("InnerFill", true)
    if not innerFill then
    warn(string.format("Tentative d'hydrater le curseur %s mais impossible de trouver InnerFill", object:GetFullName()))
    end
    local dragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")
    if not dragDetector then
    warn(string.format("Tentative d'hydrater le curseur %s mais impossible de trouver UIDragDetector", object:GetFullName()))
    end
    local self = setmetatable({
    handle = handle,
    innerFill = innerFill,
    dragDetector = dragDetector,
    value = initialValue or 0.5,
    onChanged = onChanged,
    }, SliderController)
    -- Définir la valeur initiale
    self:setValue(self.value)
    -- Connecter le détecteur à la manipulation par le joueur
    self.dragConnection = dragDetector.DragContinue:Connect(function()
    self:setValue(handle.Position.X.Scale)
    end)
    return self
    end
    function SliderController:setValue(value: Value)
    local clampedValue = math.clamp(value, 0, 1)
    self.value = clampedValue
    -- Mettre à jour la position de la poignée et la taille du cadre intérieur pour correspondre
    self.handle.Position = UDim2.fromScale(clampedValue, 0.5)
    self.innerFill.Size = UDim2.fromScale(clampedValue, 1)
    -- Exécuter le rappel de l'utilisateur avec la dernière valeur
    local changeSuccess, changeResult = pcall(self.onChanged, clampedValue)
    if not changeSuccess then
    warn("Erreur dans le rappel du curseur :", changeResult)
    end
    end
    return SliderController
    LignesBut
    746Fonction utilisée pour initialiser et attacher un comportement à un élément de curseur, acceptant le parent Frame du curseur comme object, une fonction de rappel onChanged pour traiter les changements de curseur, et une valeur initiale pour la position de la poignée du curseur. À l'intérieur de la fonction, les lignes 1427 confirment que les éléments poignée, remplissage intérieur, et UIDragDetector existent. La ligne 38 appelle la fonction setValue() du module et les lignes 4143 connectent l'événement DragContinue du détecteur de glissement à la fonction setValue() du module (voir la ligne suivante pour plus de détails).
    4861Fonction utilisée pour définir la valeur du curseur. À l'intérieur de la fonction, les lignes 5354 garantissent que la position de la poignée et la taille du remplissage intérieur sont synchronisées, et la ligne 57 passe la valeur changée à la fonction de rappel afin que vous puissiez utiliser la valeur comme nécessaire.

Créer le script de paramètres

Avec le bouton de paramètres et le menu de paramètres finalisés, vous pouvez tout relier avec un seul script qui utilise les modules de contrôle.

  1. Insérez un nouveau LocalScript dans HUDContainer et renommez-le en SettingsScript pour décrire son objectif. Notez que ce script doit être au même niveau (frère) que SettingsMenu et SettingsButton, les objets UI de premier niveau qu'il gérera.

    Fenêtre Explorer montrant le script SettingsScript à l'intérieur du conteneur HUDContainer.
  2. Collez le code suivant à l'intérieur du script :

    SettingsScript
    local ReplicatedStorage = game:GetService("ReplicatedStorage")
    local SoundService = game:GetService("SoundService")
    local SliderController = require(ReplicatedStorage.SliderController)
    local StatefulObjectController = require(ReplicatedStorage.StatefulObjectController)
    local HUDContainer = script.Parent
    -- Initialiser le bouton de paramètres
    local settingsButton = StatefulObjectController.hydrate({
    object = HUDContainer:FindFirstChild("SettingsButton"),
    states = {
    menuOpen = {
    transition = TweenInfo.new(0.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out),
    properties = {
    Rotation = 45,
    },
    },
    menuClosed = {
    transition = TweenInfo.new(0.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out),
    properties = {
    Rotation = 0,
    },
    },
    },
    initialStateName = "menuClosed"
    })
    -- Initialiser le cadre du menu de paramètres
    local settingsMenu = StatefulObjectController.hydrate({
    object = HUDContainer:FindFirstChild("SettingsMenu"),
    states = {
    menuOpen = {
    transition = TweenInfo.new(0.5, Enum.EasingStyle.Bounce, Enum.EasingDirection.Out),
    properties = {
    Position = UDim2.fromScale(0.5, 0.5),
    Visible = true,
    },
    },
    menuClosed = {
    transition = TweenInfo.new(0),
    properties = {
    Position = UDim2.fromScale(0.5, 0.4),
    Visible = false,
    },
    },
    },
    initialStateName = "menuClosed"
    })
    -- Initialiser le curseur de volume des effets
    local effectsAudio = SoundService:FindFirstChild("Effects")
    local effectsVolumeSlider = SliderController.hydrate({
    object = HUDContainer:FindFirstChild("EffectsVolumeSlider", true),
    initialValue = effectsAudio and effectsAudio.Volume or 0.5,
    onChanged = function(value: SliderController.Value)
    if effectsAudio then
    effectsAudio.Volume = value
    end
    end,
    })
    -- Initialiser le curseur de volume de fond
    local backgroundAudio = SoundService:FindFirstChild("Background")
    local backgroundVolumeSlider = SliderController.hydrate({
    object = HUDContainer:FindFirstChild("BackgroundVolumeSlider", true),
    initialValue = backgroundAudio and backgroundAudio.Volume or 0.5,
    onChanged = function(value: SliderController.Value)
    if backgroundAudio then
    backgroundAudio.Volume = value
    end
    end,
    })
    -- Connecter les boutons à l'interaction du joueur
    HUDContainer:FindFirstChild("SettingsButton").Activated:Connect(function()
    local targetState = if settingsButton.currentStateName == "menuClosed"
    then "menuOpen"
    else "menuClosed"
    settingsButton:setState(targetState)
    settingsMenu:setState(targetState)
    end)
    HUDContainer:FindFirstChild("CloseButton", true).Activated:Connect(function()
    settingsButton:setState("menuClosed")
    settingsMenu:setState("menuClosed")
    end)
  3. Référez-vous aux sections suivantes pour explorer comment le script utilise les modules de contrôle.

    Les lignes 10-27 initialisent et attachent un comportement au bouton de paramètres comme suit :

    LignesBut
    1011Une référence locale settingsButton est déclarée et hydratée avec la fonction StatefulObjectController.hydrate(), et le bouton SettingsButton à l'intérieur de HUDContainer est référencé comme l'objet à hydrater.
    1225Une table states est passée avec deux états uniques, menuOpen et menuClosed. Chaque état contient une transition pour déclarer (via un TweenInfo) comment l'état particulier atteindra ses propriétés cibles définies dans la table properties. Dans ce cas, menuOpen déclare un changement d'état à 45° pour la Rotation du bouton avec un tween Exponential de ½ seconde, tandis que menuClosed restaure effectivement le bouton à sa rotation par défaut de 0.
    26L'état initial du bouton est défini sur menuClosed (cela pourrait être défini sur n'importe quel nom d'état dans la table states).

    Plus bas dans le script (lignes 76-86), les boutons sont connectés à l'interaction du joueur pour déclencher des changements d'état de l'UI :

    LignesBut
    7682SettingsButton est connecté à l'événement Activated de la classe GuiButton pour appeler une fonction anonyme. À l'intérieur de la fonction anonyme, les lignes 7779 basculent une variable targetState entre menuOpen et menuClosed. La ligne 80 appelle ensuite setState() pour définir l'état du bouton sur targetState et la ligne `81 fait de même pour SettingsMenu afin qu'il s'ouvre ou se ferme avec l'activation de SettingsButton.
    8386CloseButton est connecté à l'événement Activated pour appeler une fonction anonyme qui définit l'état de SettingsButton et SettingsMenu sur menuClosed.

    Les lignes 30-49 initialisent et attachent un comportement au menu de paramètres comme suit :

    LignesBut
    3031Une référence locale settingsMenu est déclarée et hydratée avec la fonction StatefulObjectController.hydrate() et le cadre SettingsMenu à l'intérieur de HUDContainer est référencé comme l'objet à hydrater.
    3246Semblable au bouton de paramètres, une table states est passée avec deux états uniques, menuOpen et menuClosed. Ici, menuOpen déclare un changement d'état à UDim2.fromScale(0.5, 0.5) pour la Position du cadre avec un tween Bounce de ½ seconde, ainsi qu'un état Visible de true. En revanche, menuClosed déclare un changement d'état de position à UDim2.fromScale(0.5, 0.4) et Visible à false, mais le TweenInfo avec une durée de 0 à la ligne 41 rend effectivement le changement d'état instantané.
    48L'état initial du cadre est défini sur menuClosed.

    Plus bas dans le script (lignes 76-86), le menu de paramètres est lié à l'interaction du joueur :

    LignesBut
    81Définit le même targetState pour SettingsMenu pour se synchroniser avec l'activation de SettingsButton.
    85Définit l'état de SettingsMenu sur menuClosed lorsque CloseButton est activé.

    Les lignes 51-73 initialisent et attachent un comportement aux EffectsVolumeSlider et BackgroundVolumeSlider comme suit :

    LignesBut
    52Définit une référence locale au SoundGroup Effects à l'intérieur de SoundService. Un SoundGroup vous permet d'interrelier plusieurs Sounds et de contrôler le volume de chaque son dans le groupe via la propriété Volume du groupe.
    5354Une référence locale effectsVolumeSlider est déclarée et hydratée avec la fonction SliderController.hydrate() et le cadre EffectsVolumeSlider à l'intérieur de HUDContainer ⟩ SettingsMenu est référencé comme l'objet à hydrater. Notez que le deuxième paramètre de true pour FindFirstChild() indique à la méthode de rechercher récursivement dans la branche HUDContainer pour localiser EffectsVolumeSlider.
    55La valeur initiale du curseur est définie sur le Volume actuel du groupe sonore Effects, ou 0.5 comme valeur de repli.
    5660Établit la fonction de rappel pour appliquer les changements de valeur du curseur au volume du groupe sonore Effects.
    6473Essentiellement le même que les lignes 52-61, sauf pour hydrater le cadre BackgroundVolumeSlider à l'intérieur de HUDContainer ⟩ SettingsMenu et appliquer les changements de valeur du curseur au volume du groupe sonore Background.

Avec SettingsScript en place, le jeu propose maintenant un exemple d'interface utilisateur interactive entièrement opérationnel qui relie un ensemble d'objets UI connexes à l'interaction du joueur.

©2026 Société Roblox. Roblox, le logo Roblox et Powering Imagination font partie de nos marques déposées aux États-Unis et dans d'autres pays.