Commencer
Tutoriels intermédiaires

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.

Une HUD (Heads-Up Display) dans votre expérience affiche généralement des éléments d'interface utilisateur non interactifs, tels que le mètre de santé démontré dans Créer des mètres HUD. De plus, presque chaque expérience nécessite une interface utilisateur interactive telle que des boutons qui répondent à l'activation du joueur, s'animent lorsqu'ils sont activés, ajoutent des menus en entrée/sortie avec d'autres contrôles interactifs, etc.

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

En utilisant Les fondamentaux de l'UI - Mètre HUD comme point de départ et Les fondamentaux de l'UI - Interactivité comme référence finale, 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 déplaçables.
  • Utilisation d'un ModuleScripts pour former des modules de "contrôleur" pour le contrôle extensible des objets d'UI avec des déclarations d'état.
  • Comment connecter des boutons à l'activation du joueur pour afficher/masquer le menu des paramètres.
  • Comment connecter des curseurs d'interface utilisateur déplaçables pour ajuster séparément le volume des effets sonores et de l'ambiance de fond.

Activer l'émulateur de dispositif

Comme mentionné dans Créer des mètres HUD, les téléphones et les tablettes ont la plus petite surface 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 dispositif dans Studio :

  1. Ouvrez le modèle Les fondamentaux de l'UI - Mètre HUD dans Studio.

  2. Dans le menu Test de Studio, activez l'Émulateur de dispositif.

  3. Dans la barre située juste au-dessus de la vue principale, sélectionnez une émulation de téléphone telle que iPhone X ou Samsung Galaxy A51. Ensuite, réglez 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 dispositif 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 des paramètres.

Composant Roblox utilisé pour le bouton des 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 au centre du haut)
    • Size = 0.1, 0, 0.1, 0 (10% de la hauteur de l'écran une fois que le rapport d'aspect est contraint)
    • Image = rbxassetid://104919049969988 (ID de l'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 à inf, 44.

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

Créer le menu des 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 les niveaux de volume de l'audio de fond et des effets sonores indépendamment.

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

Créer le cadre parent

Comme noté dans Créer des mètres HUD, un Frame sert de conteneur pour d'autres objets d'interface utilisateur. Le menu des paramètres complet 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 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 arrière-plan transparent bleu marine.
  3. Insérez un UIAspectRatioConstraint dans SettingsMenu et définissez sa propriété AspectRatio à 2.5. (2.5:1 largeur/hauteur).

    Fenêtre Explorer montrant un nouveau UISizeConstraint inséré dans le cadre SettingsMenu.
    Fenêtre des 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 à 0.1, 0.

    Fenêtre Explorer montrant un nouveau UICorner inséré dans le cadre SettingsMenu.
    Fenêtre des 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 à 800, inf et son MinSize à 350, 0.

    Fenêtre Explorer montrant un nouveau UISizeConstraint inséré dans le cadre SettingsMenu.
    Fenêtre des 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 des paramètres contiendra deux widgets curseurs déplaçables 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'organiser automatiquement les GuiObjects frères et sœurs en rangées horizontales ou en 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 tout le conteneur parent, en remplaçant leur largeur définie)
    • VerticalAlignment = Center (aligner les éléments selon leur centre vertical)

Icône du curseur

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

Icône indiquant l'objectif du curseur dans le menu des 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 de l'expérience 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 que le rapport d'aspect est contraint)
    • Image = rbxassetid://90019827067389 (ID de l'actif de la note audio et du symbole "bursts")
  3. Insérez un UIAspectRatioConstraint dans Icon et laissez ses propriétés aux valeurs par défaut (rapport 1:1 largeur/hauteur).

    Fenêtre Explorer montrant un UIAspectRatioConstraint inséré dans l'ImageLabel. Icône finalisée dans le menu des 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 de curseur positionné à droite de l'icône.

Poignée interactive

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

Poignée interactive du curseur 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 que le rapport d'aspect est contraint)
    • ZIndex = 3 (couche gérant la poignée visuellement devant d'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 traînage 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. 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 propriété BoundingUI du détecteur reflète désormais le conteneur SliderFrame :

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

Si vous testez l'expérience maintenant, vous pourrez faire 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.

Portion 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 la largeur et 100% de la hauteur du cadre parent)
    • ZIndex = 2 (couche visuellement devant le remplissage/le contour du cadre parent)
  3. Pour correspondre à la forme de "pilule" du conteneur parent SliderFrame, insérez un modificateur UICorner et définissez sa propriété CornerRadius à 0.5, 0.

    Fenêtre Explorer montrant un modificateur UICorner inséré dans le cadre InnerFill.
    Fenêtre des 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 de musique.

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

    Fenêtre Explorer montrant le EffectsVolumeSlider complet 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 à 0.5, 0, 0.7, 0 pour le déplacer en dessous du premier curseur.

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

    Fenêtre Explorer montrant l'étiquette Icon dans BackgroundVolumeSlider.
    Fenêtre des propriétés montrant les valeurs attendues pour l'étiquette Icon.
    BackgroundVolumeSlider avec 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 à [255, 0, 125] (magenta).

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

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

Créer le bouton de fermeture

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

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

    Fenêtre Explorer montrant un nouveau ImageButton inséré dans SettingsMenu et renommé CloseButton. ImageButton vide positionné dans le coin supérieur gauche du menu des 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 (insertion de 10 pixels à partir du coin supérieur droit)
    • Size = 0.15, 0, 0.15, 0 (15% de la hauteur de cadre une fois que le rapport d'aspect est contraint)
    • Image = rbxassetid://5577404210 (ID de l'actif du symbole 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 des paramètres.

Créer les modules de contrôle

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

Contrôleur d'objet avec état

Le module suivant de contrôleur d'objet avec état vous permet d'attacher un comportement aux objets d'UI tels que SettingsButton et SettingsMenu, et de basculer/tweener 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éutiliser 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 les 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 la vérification lors de l'utilisation de ce module.
    1233Fonction utilisée pour initialiser et attacher un comportement à un objet d'interface utilisateur avec état, acceptant un GuiObject comme object, une table d'états et leurs données TweenInfo respectives, 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 étant 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 permet également de connecter une fonction de rappel à chaque curseur pour détecter l'interaction du joueur avec le curseur et appliquer les modifications souhaitées dans l'expérience.

  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 du 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 de curseur, de remplissage intérieur et de UIDragDetector existent. La ligne 38 appelle la fonction setValue() du module et les lignes 4143 connectent l'événement UIDragDetector.DragContinue du détecteur à 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 souhaité.

Créer le script des paramètres

Avec le bouton de paramètres et le menu des paramètres finalisés, vous pouvez les 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 d'UI de premier niveau qu'il va gérer.

    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 des 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 d'arrière-plan
    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 des joueurs
    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 dans 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 (à travers 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 de 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 loin dans le script (lignes 76-86), les boutons sont connectés à l'interaction des joueurs 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 du 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 des 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 dans HUDContainer est référencé comme l'objet à hydrater.
    3246Semblable au bouton des 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 sur la ligne 41 rend effectivement le changement d'état instantané.
    48L'état initial du cadre est défini sur menuClosed.

    Plus loin dans le script (lignes 76-86), le menu des paramètres est lié à l'interaction des joueurs :

    LignesBut
    81Définit le même targetState pour SettingsMenu pour 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’une référence locale au Effect SoundGroup dans SoundService. Un SoundGroup vous permet de créer des liants entre plusieurs Sounds et de contrôler le volume de chaque son du 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 dans HUDContainer ⟩ SettingsMenu est référencé comme l'objet à hydrater. Notez que le deuxième paramètre de true pour FindFirstChild() dit à la méthode de chercher de manière récursive dans la branche HUDContainer pour localiser EffectsVolumeSlider.
    55La valeur initiale du curseur est définie sur le Volume actuel du groupe Effects, ou 0.5 en tant que valeur de secours.
    5660Établit la fonction de rappel pour appliquer les changements de valeur du curseur au volume du groupe Effects.
    6473Essentiellement la même chose que les lignes 52-61, sauf pour hydrater le cadre BackgroundVolumeSlider dans HUDContainer ⟩ SettingsMenu et appliquer les changements de valeur du curseur au volume du groupe Background.

Avec SettingsScript en place, l'expérience propose désormais un exemple d'interface utilisateur interactive complètement opérationnelle qui lie un ensemble d'objets d'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.