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.

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 :
Ouvrez le modèle Les fondamentaux de l'UI - Mètre HUD dans Studio.
Dans le menu Test de Studio, activez l'Émulateur de dispositif.
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.

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.

Pour construire le bouton de paramètres :
Dans la fenêtre Explorer, localisez HUDContainer à l'intérieur de StarterGui.

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")
Insérez un UIAspectRatioConstraint dans le bouton avec les propriétés par défaut (rapport 1:1 largeur/hauteur).

Pour limiter la hauteur maximale en pixels du bouton, insérez un UISizeConstraint et définissez son MaxSize à inf, 44.



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.

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.
Insérez un Frame dans HUDContainer et renommez-le en SettingsMenu.

Avec SettingsMenu sélectionné, définissez les propriétés suivantes :
- AnchorPoint = 0.5 (ancre centrale)
- BackgroundColor3 = 30, 30, 60 (bleu marine)
- BackgroundTransparency = 0.25 (75% opaque)
- Position = 0.5, 0, 0.5, 0 (centre de l'écran)
- Size = 0.75, 0, 0.75, 0 (75% de la largeur/hauteur de la zone d'écran intérieure)

Insérez un UIAspectRatioConstraint dans SettingsMenu et définissez sa propriété AspectRatio à 2.5. (2.5:1 largeur/hauteur).


Insérez un modificateur UICorner dans SettingsMenu et définissez sa propriété CornerRadius à 0.1, 0.


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.



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 :
Insérez un nouveau Frame dans le conteneur SettingsMenu et renommez-le en EffectsVolumeSlider.

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)

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.

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.

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.

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")
Insérez un UIAspectRatioConstraint dans Icon et laissez ses propriétés aux valeurs par défaut (rapport 1:1 largeur/hauteur).


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

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.

Avec SliderFrame sélectionné, définissez les propriétés suivantes :
- BackgroundColor3 = 0 (noir)
- BackgroundTransparency = 0.75 (25% opaque)
- LayoutOrder = 1
- Size = 1, 0, 1, 0 (100% de la largeur/hauteur du cadre parent)
Insérez les modificateurs suivants dans SliderFrame :
- UIStroke avec sa Color définie à 0, Thickness à 3, et Transparency à 0.25 (contour noir opaque à 75%)

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.

Insérez un nouveau Frame dans le conteneur SliderFrame et renommez-le en Handle.

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)
Insérez les modificateurs suivants dans Handle :
- UIAspectRatioConstraint avec ses propriétés par défaut (1:1 largeur/hauteur)
Insérez un objet UIDragDetector dans Handle. Cet objet pratique facilite et encourage l'interaction avec des éléments d'interface utilisateur 2D.

Définissez les propriétés suivantes pour le nouveau UIDragDetector :
- ResponseStyle = Scale (déplacement par valeurs d'échelle de la position du parent du détecteur)
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 :
- Sélectionnez le UIDragDetector.
- Cliquez sur sa propriété BoundingUI dans la fenêtre Propriétés.
- Dans la fenêtre Explorer, cliquez sur le parent SliderFrame de la poignée.

La propriété BoundingUI du détecteur reflète désormais le 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.

Insérez un nouveau Frame dans le conteneur SliderFrame et renommez-le en InnerFill.

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)
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.



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.

Sélectionnez l'objet complet EffectsVolumeSlider.

Dupliquez-le (CtrlD ou ⌘D) puis renommez le duplicata en BackgroundVolumeSlider.

Changez la Position du duplicata à 0.5, 0, 0.7, 0 pour le déplacer en dessous du premier curseur.

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).



Sélectionnez le cadre InnerFill dans SliderFrame et changez sa propriété BackgroundColor3 en même couleur magenta ([255, 0, 125]).



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).

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)
Insérez un UIAspectRatioConstraint dans le bouton avec les propriétés par défaut (1:1 largeur/hauteur).


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 :
Insérez un ModuleScript dans le conteneur ReplicatedStorage et renommez-le en StatefulObjectController.

Collez le code suivant à l'intérieur du module :
StatefulObjectControllerlocal TweenService = game:GetService("TweenService")local StatefulObjectController = {}StatefulObjectController.__index = StatefulObjectControllerexport type StateName = stringexport 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.initialStateNamelocal 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 changefor stateName, state in states doself.tweens[stateName] = TweenService:Create(object, state.transition, state.properties)endself:setState(self.currentStateName)return selfendfunction StatefulObjectController:setState(stateName: StateName)local stateTween: Tween = self.tweens[stateName]if not stateTween thenwarn(string.format("Tentative de définir %s à un état inconnu '%s'", self.object:GetFullName(), stateName))returnendself.currentStateName = stateName-- Assurez-vous que les autres tweens ne sont pas en conflitfor _, tween in self.tweens dotween:Cancel()endstateTween:Play()endreturn StatefulObjectControllerExplication du codeLignes But 6‑10 Définit et exporte les types Luau pour améliorer l'autocomplétion et la vérification lors de l'utilisation de ce module. 12‑33 Fonction 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 26‑28 construisent des Tweens pour chaque état, et la ligne 30 appelle la fonction setState() du module pour définir l'objet à l'état initial. 35‑50 Fonction 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 45‑47 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.
Insérez un ModuleScript dans le conteneur ReplicatedStorage et renommez-le en SliderController.

Collez le code suivant à l'intérieur du module :
SliderControllerlocal SliderController = {}SliderController.__index = SliderControllerexport type Value = numberexport type OnChanged = (Value) -> ()function SliderController.hydrate(props: {object: Instance,onChanged: OnChanged,initialValue: Value?})local object, onChanged, initialValue = props.object, props.onChanged, props.initialValuelocal handle = object:FindFirstChild("Handle", true)if not handle thenwarn(string.format("Tentative d'hydrater le curseur %s mais impossible de trouver Handle", object:GetFullName()))endlocal innerFill = object:FindFirstChild("InnerFill", true)if not innerFill thenwarn(string.format("Tentative d'hydrater le curseur %s mais impossible de trouver InnerFill", object:GetFullName()))endlocal dragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")if not dragDetector thenwarn(string.format("Tentative d'hydrater le curseur %s mais impossible de trouver UIDragDetector", object:GetFullName()))endlocal self = setmetatable({handle = handle,innerFill = innerFill,dragDetector = dragDetector,value = initialValue or 0.5,onChanged = onChanged,}, SliderController)-- Définir la valeur initialeself:setValue(self.value)-- Connecter le détecteur à la manipulation par le joueurself.dragConnection = dragDetector.DragContinue:Connect(function()self:setValue(handle.Position.X.Scale)end)return selfendfunction 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 correspondreself.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 valeurlocal changeSuccess, changeResult = pcall(self.onChanged, clampedValue)if not changeSuccess thenwarn("Erreur dans le rappel du curseur :", changeResult)endendreturn SliderControllerExplication du codeLignes But 7‑46 Fonction 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 14‑27 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 41‑43 connectent l'événement UIDragDetector.DragContinue du détecteur à la fonction setValue() du module (voir la ligne suivante pour plus de détails). 48‑61 Fonction utilisée pour définir la valeur du curseur. À l'intérieur de la fonction, les lignes 53‑54 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.
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.

Collez le code suivant à l'intérieur du script :
SettingsScriptlocal 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ètreslocal 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ètreslocal 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 effetslocal 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 theneffectsAudio.Volume = valueendend,})-- Initialiser le curseur de volume d'arrière-planlocal 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 thenbackgroundAudio.Volume = valueendend,})-- Connecter les boutons à l'interaction des joueursHUDContainer: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)Référez-vous aux sections suivantes pour explorer comment le script utilise les modules de contrôle.
Bouton des paramètresLes lignes 10-27 initialisent et attachent un comportement au bouton de paramètres comme suit :
Lignes But 10‑11 Une 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. 12‑25 Une 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. 26 L'é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 :
Lignes But 76‑82 SettingsButton est connecté à l'événement Activated de la classe GuiButton pour appeler une fonction anonyme. À l'intérieur de la fonction anonyme, les lignes 77‑79 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. 83‑86 CloseButton est connecté à l'événement Activated pour appeler une fonction anonyme qui définit l'état de SettingsButton et SettingsMenu sur menuClosed. Menu des paramètresLes lignes 30-49 initialisent et attachent un comportement au menu des paramètres comme suit :
Lignes But 30‑31 Une 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. 32‑46 Semblable 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é. 48 L'é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 :
Lignes But 81 Définit le même targetState pour SettingsMenu pour synchroniser avec l'activation de SettingsButton. 85 Définit l'état de SettingsMenu sur menuClosed lorsque CloseButton est activé. Curseurs de volumeLes lignes 51-73 initialisent et attachent un comportement aux EffectsVolumeSlider et BackgroundVolumeSlider comme suit :
Lignes But 52 D’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. 53‑54 Une 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. 55 La valeur initiale du curseur est définie sur le Volume actuel du groupe Effects, ou 0.5 en tant que valeur de secours. 56‑60 Établit la fonction de rappel pour appliquer les changements de valeur du curseur au volume du groupe Effects. 64‑73 Essentiellement 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.






