Inizia
Tutorial intermedi

Crea un'interfaccia utente interattiva

*Questo contenuto è tradotto usando AI (Beta) e potrebbe contenere errori. Per visualizzare questa pagina in inglese, clicca qui.

Un HUD (Heads-Up Display) nella tua esperienza visualizza comunemente elementi UI non interattivi come il misuratore di salute dimostrato in Crea misuratori HUD. Inoltre, quasi ogni esperienza richiede un'interfaccia utente interattiva come pulsanti che rispondono all'attivazione del giocatore, che animano quando attivato, che mostrano/occultano menu con altri controlli interattivi, ecc.

Vista in gioco che mostra un pulsante delle impostazioni e un menu delle impostazioni con cursori di volume.

Utilizzando UI Fundamentals - Misuratore HUD come punto di partenza e UI Fundamentals - Interattività come riferimento finale, questo tutorial dimostra:

  • Come posizionare un pulsante delle impostazioni lungo il margine superiore dello schermo.
  • Design di un menu delle impostazioni contenente cursori interattivi trascinabili.
  • Utilizzo di un ModuleScripts per formare moduli "controller" per il controllo estensibile degli oggetti UI con dichiarazioni a stato.
  • Come collegare pulsanti all'attivazione del giocatore per mostrare/nascondere il menu delle impostazioni.
  • Come collegare cursori UI trascinabili per regolare separatamente il volume degli effetti sonori e dell'atmosfera di sottofondo.

Abilita l'emulatore di dispositivo

Come indicato in Crea misuratori HUD, telefoni e tablet hanno la minor quantità di spazio su schermo, quindi è importante che i tuoi elementi UI si adattino a schermi più piccoli e che siano chiaramente visibili per i giocatori. Se non lo hai già fatto, abilita l'Emulatore di dispositivo in Studio:

  1. Apri il UI Fundamentals - Misuratore HUD template in Studio.

  2. Dal menu Test di Studio, attiva Emulatore di dispositivo.

  3. Dalla barra direttamente sopra il viewport principale, seleziona un'emulazione di telefono come iPhone X o Samsung Galaxy A51. Poi, imposta la dimensione di visualizzazione su Adatta alla finestra per utilizzare al massimo lo spazio in Studio.

    Opzioni di impostazione dell'emulatore di dispositivo indicate nella parte superiore della finestra del viewport.

Crea il pulsante delle impostazioni

GuiButtons sono elementi interattivi dell'interfaccia utente con funzionalità integrate come l'evento multi-piattaforma Activated che si attiva quando il pulsante viene cliccato o toccato. La classe GuiButton si estende in due variazioni, TextButton e ImageButton, e questo tutorial utilizza un ImageButton a forma di "ingranaggio" per attivare o chiudere il menu delle impostazioni.

Componente Roblox utilizzato per il pulsante delle impostazioni.

Per costruire il pulsante delle impostazioni:

  1. Nella finestra Explorer, individua HUDContainer all'interno di StarterGui.

    Finestra di Explorer che mostra il HUDContainer selezionato.
  2. Inserisci un ImageButton in HUDContainer e rinominalo in SettingsButton.

    Finestra di Explorer che mostra un nuovo ImageButton inserito e rinominato in SettingsButton. Nuovo ImageButton nel viewport.
  3. Con il nuovo pulsante selezionato, imposta i seguenti valori nella finestra Proprietà:

    • AnchorPoint = 0.5, 0.25 (centro orizzontale e quarto superiore verticale)
    • BackgroundTransparency = 1 (completamente trasparente)
    • Position = 0.5, 0, 0, 0 (posizionamento al centro in alto)
    • Size = 0.1, 0, 0.1, 0 (10% dell'altezza dello schermo una volta constraint il rapporto d'aspetto)
    • Image = rbxassetid://104919049969988 (ID dell'asset del simbolo "ingranaggio")
  4. Inserisci un UIAspectRatioConstraint nel pulsante con proprietà di default (rapporto di 1:1 tra larghezza e altezza).

    Finestra di Explorer che mostra un nuovo UIAspectRatioConstraint inserito nel pulsante SettingsButton.
  5. Per limitare l'altezza massima in pixel del pulsante, inserisci un UISizeConstraint e imposta il suo MaxSize su inf, 44.

    Finestra di Explorer che mostra un nuovo UISizeConstraint inserito nel pulsante SettingsButton.
    Finestra delle proprietà che mostra i valori attesi per il nuovo UISizeConstraint.
    Pulsante delle impostazioni finale al centro in alto dello schermo.

Crea il menu delle impostazioni

Il nuovo pulsante delle impostazioni sarà programmato per attivare e chiudere un menu delle impostazioni, dando ai giocatori accesso on-demand a impostazioni o altre informazioni. In questo tutorial, il menu conterrà cursori interattivi per regolare indipendentemente i livelli di volume dell'audio di sottofondo e degli effetti sonori.

Componenti di base utilizzati per il menu delle impostazioni.

Crea il frame genitore

Come indicato in Crea misuratori HUD, un Frame funge da contenitore per altri oggetti UI. L'intero menu delle impostazioni sarà costruito con un singolo frame genitore, rendendolo semplice da gestire come un oggetto a stato che reagisce diversamente all'input a seconda dello stato attuale.

  1. Inserisci un Frame in HUDContainer e rinominalo in SettingsMenu.

    Finestra di Explorer che mostra un nuovo frame inserito e rinominato in SettingsMenu.
  2. Con SettingsMenu selezionato, imposta le seguenti proprietà:

    Frame riposizionato, ridimensionato e stilizzato con uno sfondo blu navy trasparente.
  3. Inserisci un UIAspectRatioConstraint in SettingsMenu e imposta la sua proprietà AspectRatio su 2.5. (rapporto di 2.5:1 tra larghezza e altezza).

    Finestra di Explorer che mostra un nuovo UISizeConstraint inserito nel frame SettingsMenu.
    Finestra delle proprietà che mostra i valori attesi per il nuovo UISizeConstraint.
  4. Inserisci un modificatore UICorner in SettingsMenu e imposta il suo CornerRadius su 0.1, 0.

    Finestra di Explorer che mostra un nuovo UICorner inserito nel frame SettingsMenu.
    Finestra delle proprietà che mostra i valori attesi per il nuovo modificatore UICorner.
  5. Per vincolare la larghezza e l'altezza in pixel di SettingsMenu, inserisci un UISizeConstraint. Imposta il suo MaxSize su 800, inf e il suo MinSize su 350, 0.

    Finestra di Explorer che mostra un nuovo UISizeConstraint inserito nel frame SettingsMenu.
    Finestra delle proprietà che mostra i valori attesi per il nuovo UISizeConstraint.
    Frame stilizzato con angoli arrotondati.

Costruisci un cursore

Per consentire ai giocatori di regolare i livelli di volume, il menu delle impostazioni conterrà due widget di cursore trascinabili alimentati da UIDragDetector, un oggetto conveniente che facilita l'interazione con elementi dell'interfaccia utente 2D.


Per creare un contenitore genitore per il primo cursore:

  1. Inserisci un nuovo Frame nel contenitore SettingsMenu e rinominalo EffectsVolumeSlider.

    Finestra di Explorer che mostra un nuovo frame inserito nel frame SettingsMenu, rinominato in EffectsVolumeSlider.
  2. Con il frame EffectsVolumeSlider selezionato, imposta le seguenti proprietà:

    • AnchorPoint = 0.5 (ancora centrale)

    • BackgroundTransparency = 1 (completamente trasparente)

    • Position = 0.5, 0, 0.35, 0 (centro orizzontale e 35% dall'alto del contenitore)

    • Size = 0.8, 0, 0.1, 0 (80% della larghezza del contenitore e 10% della sua altezza)

      Frame vuoto inserito per contenere gli elementi del cursore.
  3. Inserisci un nuovo UIListLayout in EffectsVolumeSlider. Questo modificatore di layout è un modo potente per disporre automaticamente GuiObjects fraterni in righe orizzontali o colonne verticali all'interno del loro contenitore genitore, inclusa la possibilità di applicare concetti di flessibilità.

    Finestra di Explorer che mostra un nuovo UIListLayout inserito nel frame EffectsVolumeSlider.
  4. Imposta le seguenti proprietà per il nuovo UIListLayout:

    • Padding = 0.06, 0 (padding del 6% tra gli elementi della lista)
    • FillDirection = Horizontal (disposizione da sinistra a destra degli elementi)
    • HorizontalFlex = Fill (ridimensiona gli elementi orizzontalmente per riempire l'intero contenitore genitore, sovrascrivendo la loro larghezza definita)
    • VerticalAlignment = Center (allinea gli elementi lungo il loro centro verticale)

Icona del cursore

Un'icona semplice che include una nota audio e un simbolo di "esplosione" aiuta i giocatori a identificare lo scopo del cursore quando aprono il menu delle impostazioni.

Icona che indica lo scopo del cursore nel menu delle impostazioni.
  1. Inserisci un ImageLabel nel frame EffectsVolumeSlider e rinominalo in Icon. Questa icona aiuterà i giocatori a capire a quale aspetto dell'esperienza il cursore controlla.

    Finestra di Explorer che mostra un ImageLabel inserito nel frame EffectsVolumeSlider.
  2. Con Icon selezionato, imposta le seguenti proprietà:

    • BackgroundTransparency = 1 (completamente trasparente)
    • Size = 2.5, 0, 2.5, 0 (250% dell'altezza del frame genitore una volta constraint il rapporto d'aspetto)
    • Image = rbxassetid://90019827067389 (ID dell'asset della nota audio e simbolo di "esplosione")
  3. Inserisci un UIAspectRatioConstraint in Icon e lascia le sue proprietà come le impostazioni di default (1:1 tra larghezza e altezza).

    Finestra di Explorer che mostra un UIAspectRatioConstraint inserito nell'ImageLabel. Icona finalizzata nel menu delle impostazioni.

Frame di intervallo

Direttamente a destra dell' icona, la parte interattiva del cursore dovrebbe essere contenuta all'interno di un altro Frame.

Dimensione e posizione target della parte interattiva del cursore.
  1. Inserisci un nuovo Frame nel frame EffectsVolumeSlider e rinominalo SliderFrame. Nota che deve essere un fratello diretto del modificatore di layout UIListLayout.

    Finestra di Explorer che mostra un Frame figlio inserito nel frame EffectsVolumeSlider.
  2. Con SliderFrame selezionato, imposta le seguenti proprietà:

  3. Inserisci i seguenti modificatori in SliderFrame:

    Frame del cursore posizionato a destra dell'icona.

Maniglia interattiva

Con il contenitore del cursore costruito, ora puoi creare una maniglia trascinabile con cui i giocatori possono interagire durante il gioco.

Maniglia interattiva del cursore posizionata all'interno del range frame.
  1. Inserisci un nuovo Frame nel contenitore SliderFrame e rinominalo in Handle.

    Finestra di Explorer che mostra un Frame figlio inserito nel frame SliderFrame e rinominato in Handle.
  2. Con Handle selezionato, imposta le seguenti proprietà:

    • AnchorPoint = 0.5 (ancora centrale)
    • Position = 0.5, 0, 0.5, 0 (centro orizzontale e verticale del frame genitore)
    • Size = 1.2, 0, 1.2, 0 (120% dell'altezza del frame genitore una volta constraint il rapporto d'aspetto)
    • ZIndex = 3 (disposiziona la maniglia visivamente davanti ad altri elementi del cursore)
  3. Inserisci i seguenti modificatori in Handle:

  4. Inserisci un oggetto UIDragDetector in Handle. Questo oggetto conveniente facilita e incoraggia l'interazione con elementi dell'interfaccia utente 2D.

    Finestra di Explorer che mostra un UIDragDetector inserito nel frame Handle.
  5. Imposta le seguenti proprietà per il nuovo UIDragDetector:

  6. Per garantire che l'intervallo di trascinamento lineare della maniglia sia limitato al suo contenitore, collega la sua proprietà BoundingUI al contenitore SliderFrame:

    1. Seleziona il UIDragDetector.
    2. Clicca sulla sua proprietà BoundingUI nella finestra Proprietà.
    3. Torna nella finestra Explorer e clicca sul genitore SliderFrame della maniglia.
    Diagramma che mostra il processo di collegamento della proprietà BoundingUI del detector al contenitore SliderFrame.

    Il collegamento ora riflette la proprietà BoundingUI del contenitore SliderFrame:

    Finestra delle proprietà che mostra la proprietà BoundingUI del detector collegata al contenitore SliderFrame.

Se ora provi l'esperienza, sarai in grado di trascinare la maniglia a sinistra e a destra all'interno del suo contenitore genitore:

Riempimento interno

Per indicare più chiaramente che il cursore controlla un intervallo dal 0% al 100%, puoi aggiungere un riempimento interno sul lato sinistro del contenitore che si sincronizzerà con la posizione variabile della maniglia.

Parte interna del cursore inserita nello SliderFrame.
  1. Inserisci un nuovo Frame nel contenitore SliderFrame e rinominalo in InnerFill.

    Finestra di Explorer che mostra un frame figlio inserito nel frame SliderFrame e rinominato in InnerFill.
  2. Imposta le seguenti proprietà per il frame InnerFill:

    • AnchorPoint = 0, 0.5 (bordo sinistro e centro verticale)
    • BackgroundColor3 = [0, 150, 255] (blu che corrisponde alla maniglia del cursore)
    • BackgroundTransparency = 0.35 (65% opaco)
    • Position = 0, 0, 0.5, 0
    • Size = 0.5, 0, 1, 0 (50% di larghezza e 100% di altezza del frame genitore)
    • ZIndex = 2 (disposiziona visivamente davanti al riempimento/bordo del frame genitore)
  3. Per abbinare la forma "pillola" del contenitore genitore SliderFrame, inserisci un modificatore UICorner e imposta la sua proprietà CornerRadius su 0.5, 0.

    Finestra di Explorer che mostra un modificatore UICorner inserito nel frame InnerFill.
    Finestra delle proprietà che mostra i valori attesi per il nuovo UICorner.
    Frame InnerFill stilizzato con sfondo blu e angoli arrotondati.

Duplica il cursore

Con il primo cursore costruito, puoi facilmente duplicarlo e modificare alcuni aspetti visivi per indicare un altro scopo, in questo caso il livello di volume dell'audio di sottofondo simboleggiato da un'icona di note musicali.

Posizione target del cursore audio di sottofondo.
  1. Seleziona il completato oggetto EffectsVolumeSlider.

    Finestra di Explorer che mostra il EffectsVolumeSlider completato selezionato.
  2. Duplica (CtrlD o D) e poi rinomina il duplicato in BackgroundVolumeSlider.

    Finestra di Explorer che mostra il cursore duplicato rinominato in BackgroundVolumeSlider.
  3. Cambia la Position del duplicato in 0.5, 0, 0.7, 0 per spostarlo sotto il primo cursore.

    BackgroundVolumeSlider posizionato sotto EffectsVolumeSlider.
  4. Espandi il ramo di primo livello di BackgroundVolumeSlider, seleziona l'etichetta dell'immagine Icon e cambia la sua proprietà Image in rbxassetid://101125859760167 (ID asset del simbolo con note musicali).

    Finestra di Explorer che mostra l'etichetta Icon all'interno di BackgroundVolumeSlider.
    Finestra delle proprietà che mostra i valori attesi per l'etichetta Icon.
    BackgroundVolumeSlider con immagine dell'icona modificata.
  5. Espandi il ramo SliderFrameHandle, seleziona il modificatore UIStroke al suo interno, e imposta la sua proprietà Color in [255, 0, 125] (magenta).

    Finestra di Explorer che mostra il modificatore UIStroke all'interno della maniglia di BackgroundVolumeSlider.
    Finestra delle proprietà che mostra i valori attesi per il modificatore UIStroke.
    BackgroundVolumeSlider con immagine dell'icona modificata.
  6. Seleziona il frame InnerFill all'interno di SliderFrame e cambia la sua BackgroundColor3 in lo stesso colore magenta ([255, 0, 125]).

    Finestra di Explorer che mostra il frame InnerFill all'interno del contenitore SliderFrame di BackgroundVolumeSlider.
    Finestra delle proprietà che mostra i valori attesi per il frame InnerFill.
    BackgroundVolumeSlider con colore di InnerFill modificato.

Crea il pulsante di chiusura

L'ultimo elemento del menu delle impostazioni è un pulsante di chiusura che fornisce ai giocatori un'ulteriore input per chiudere il menu (il SettingsButton al centro in alto avrà lo stesso scopo).

Menu delle impostazioni con pulsante di chiusura indicato nell'angolo superiore destro.
  1. Inserisci un nuovo ImageButton nel contenitore SettingsMenu e rinominalo in CloseButton.

    Finestra di Explorer che mostra un nuovo ImageButton inserito nel SettingsMenu e rinominato in CloseButton. ImageButton vuoto posizionato nell'angolo in alto a sinistra del menu delle impostazioni.
  2. Con CloseButton selezionato, imposta le seguenti proprietà:

    • AnchorPoint = 1, 0 (angolo in alto a destra)
    • BackgroundTransparency = 1 (completamente trasparente)
    • Position = 1, -10, 0, 10 (10 pixel di margine dall'angolo in alto a destra)
    • Size = 0.15, 0, 0.15, 0 (15% dell'altezza del frame una volta constraint il rapporto d'aspetto)
    • Image = rbxassetid://5577404210 (ID asset del simbolo di chiusura)
    • ImageTransparency = 0.25 (75% opaco)
  3. Inserisci un UIAspectRatioConstraint nel pulsante con proprietà di default (1:1 tra larghezza e altezza).

    Finestra di Explorer che mostra un UIAspectRatioConstraint inserito nel pulsante CloseButton. Pulsante di chiusura finalizzato nell'angolo in alto a destra del menu delle impostazioni.

Crea i moduli di controllo

Un setup di modulo di controllo estensibile rende la gestione dell'UI interattiva più snella rispetto a singoli script posizionati all'interno di ogni oggetto. ModuleScripts facilitano questa funzionalità estensibile consentendo di riutilizzare codice tra script su lati differenti del confine client-server o lo stesso lato del confine.

Controller di oggetti a stato

Il seguente modulo di controller di oggetti a stato ti consente di allegare comportamenti agli oggetti UI come SettingsButton e SettingsMenu, e facilmente attivare/tweenare tra vari stati. Per creare il modulo:

  1. Inserisci un ModuleScript nel contenitore ReplicatedStorage e rinominalo in StatefulObjectController.

    Finestra di Explorer che mostra il modulo StatefulObjectController all'interno del contenitore ReplicatedStorage.
  2. Incolla il seguente codice all'interno del modulo:

    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)
    -- Crea tweens per riutilizzo per evitare di crearne di nuovi ogni volta che lo stato cambia
    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("Tentativo di impostare %s a uno stato sconosciuto '%s'", self.object:GetFullName(), stateName))
    return
    end
    self.currentStateName = stateName
    -- Assicurati che altri tweens non siano in conflitto
    for _, tween in self.tweens do
    tween:Cancel()
    end
    stateTween:Play()
    end
    return StatefulObjectController
    LineeScopo
    610Definisce ed esporta i tipi Luau per migliorare l'auto completamento e il linting quando si utilizza questo modulo.
    1233Funzione utilizzata per inizializzare e allegare comportamenti a un oggetto interattivo a stato, accettando un GuiObject come object, una tabella di stati e i rispettivi dati TweenInfo, e un nome di stato iniziale. All'interno di questa funzione, le linee 2628 costruiscono Tweens per ciascuno stato, e la linea 30 chiama la funzione setState() del modulo per impostare l'oggetto allo stato iniziale.
    3550Funzione utilizzata per impostare/cambiare lo stato di un oggetto a stato. All'interno della funzione, la linea 42 imposta il currentStateName dell'oggetto allo stato impostato, le linee 4547 annullano eventuali tweens in esecuzione per prevenire conflitti, e la linea 49 esegue il tween dello stato.

Controller del cursore

Un ulteriore modulo inizializza e controlla i due cursori di volume. Consente anche di collegare una funzione di callback a ciascun cursore per rilevare l'interazione del giocatore con il cursore e applicare le modifiche desiderate nell'esperienza.

  1. Inserisci un ModuleScript nel contenitore ReplicatedStorage e rinominalo in SliderController.

    Finestra di Explorer che mostra il modulo SliderController all'interno del contenitore ReplicatedStorage.
  2. Incolla il seguente codice all'interno del modulo:

    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("Tentativo di idratare il cursore %s ma non è riuscito a trovare la maniglia", object:GetFullName()))
    end
    local innerFill = object:FindFirstChild("InnerFill", true)
    if not innerFill then
    warn(string.format("Tentativo di idratare il cursore %s ma non è riuscito a trovare InnerFill", object:GetFullName()))
    end
    local dragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")
    if not dragDetector then
    warn(string.format("Tentativo di idratare il cursore %s ma non è riuscito a trovare UIDragDetector", object:GetFullName()))
    end
    local self = setmetatable({
    handle = handle,
    innerFill = innerFill,
    dragDetector = dragDetector,
    value = initialValue or 0.5,
    onChanged = onChanged,
    }, SliderController)
    -- Imposta il valore iniziale
    self:setValue(self.value)
    -- Collega il detector alla manipolazione del giocatore
    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
    -- Aggiorna la posizione della maniglia e la dimensione del riempimento interno per corrispondere
    self.handle.Position = UDim2.fromScale(clampedValue, 0.5)
    self.innerFill.Size = UDim2.fromScale(clampedValue, 1)
    -- Esegui la callback dell'utente con l'ultimo valore
    local changeSuccess, changeResult = pcall(self.onChanged, clampedValue)
    if not changeSuccess then
    warn("Errore nella callback del cursore:", changeResult)
    end
    end
    return SliderController
    LineeScopo
    746Funzione utilizzata per inizializzare e allegare comportamenti a un elemento cursore, accettando il Frame genitore del cursore come object, una funzione di callback onChanged per elaborare le modifiche al cursore, e un valore iniziale per la posizione della maniglia del cursore. All'interno della funzione, le linee 1427 confermano che esistano gli elementi maniglia, riempimento interno e UIDragDetector del cursore. La linea 38 chiama la funzione setValue() del modulo e le linee 4143 collegano l'evento DragContinue del detector alla funzione setValue() del modulo (vedi la riga successiva per i dettagli).
    4861Funzione utilizzata per impostare il valore del cursore. All'interno della funzione, le linee 5354 assicurano che la posizione della maniglia e la dimensione del riempimento interno siano sincronizzate, e la linea 57 passa il valore modificato alla funzione di callback così da poter utilizzare il valore come necessario.

Crea lo script delle impostazioni

Con il pulsante delle impostazioni e il menu delle impostazioni finalizzati, puoi unire tutto con un singolo script che utilizza i moduli di controllo.

  1. Inserisci un nuovo LocalScript nel HUDContainer e rinominalo in SettingsScript per descriverne lo scopo. Nota che questo script dovrebbe essere allo stesso livello (fratello) di SettingsMenu e SettingsButton, gli oggetti UI di primo livello che gestirà.

    Finestra di Explorer che mostra lo script SettingsScript all'interno del contenitore HUDContainer.
  2. Incolla il seguente codice all'interno dello 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
    -- Inizializza il pulsante delle impostazioni
    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"
    })
    -- Inizializza il frame del menu delle impostazioni
    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"
    })
    -- Inizializza il cursore del volume effetti
    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,
    })
    -- Inizializza il cursore del volume di sottofondo
    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,
    })
    -- Collega i pulsanti all'interazione del giocatore
    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. Riferisciti alle seguenti sezioni per esplorare come lo script utilizza i moduli di controllo.

    Le linee 10-27 inizializzano e allegano comportamenti al pulsante delle impostazioni come segue:

    LineeScopo
    1011Viene dichiarato un riferimento locale settingsButton e idratato con la funzione StatefulObjectController.hydrate(), e il SettingsButton all'interno di HUDContainer viene referenziato come l'oggetto da idratare.
    1225Una tabella states viene passata con due stati unici, menuOpen e menuClosed. Ogni stato contiene una transizione da dichiarare (attraverso un TweenInfo) su come il particolare stato raggiungerà le proprietà target definite nella tabella properties. In questo caso, menuOpen dichiara un cambiamento di stato a 45° per la Rotation del pulsante con un tween Exponential di ½ secondo, mentre menuClosed ripristina efficacemente il pulsante alla sua rotazione predefinita di 0.
    26Lo stato iniziale del pulsante è impostato su menuClosed (questo potrebbe essere impostato su qualsiasi nome di stato all'interno della tabella states).

    Più in basso nello script (linee 76-86), i pulsanti sono collegati all'interazione del giocatore per attivare cambiamenti di stato dell'UI:

    LineeScopo
    7682SettingsButton è collegato all'evento Activated della classe GuiButton per chiamare una funzione anonima. All'interno della funzione anonima, le linee 7779 attivano una variabile targetState tra menuOpen e menuClosed. La linea 80 chiama quindi setState() per impostare lo stato del pulsante in targetState e la linea `81 fa lo stesso per SettingsMenu in modo che si apra o chiuda con l'attivazione di SettingsButton.
    8386CloseButton è collegato all'evento Activated per chiamare una funzione anonima che imposta lo stato di SettingsButton e SettingsMenu a menuClosed.

    Le linee 30-49 inizializzano e allegano comportamenti al menu delle impostazioni come segue:

    LineeScopo
    3031Viene dichiarato un riferimento locale settingsMenu e idratato con la funzione StatefulObjectController.hydrate() e il frame SettingsMenu all'interno di HUDContainer viene referenziato come l'oggetto da idratare.
    3246Simile al pulsante delle impostazioni, viene passata una tabella states con due stati unici, menuOpen e menuClosed. Qui, menuOpen dichiara un cambiamento di stato a UDim2.fromScale(0.5, 0.5) per la Position del frame con un tween Bounce di ½ secondo, così come uno stato Visible di true. Al contrario, menuClosed dichiara un cambiamento dello stato di posizione a UDim2.fromScale(0.5, 0.4) e Visible a false, ma il TweenInfo con durata di 0 sulla linea 41 fa sì che il cambiamento di stato avvenga istantaneamente.
    48Lo stato iniziale del frame viene impostato su menuClosed.

    Più in basso nello script (linee 76-86), il menu delle impostazioni è collegato all'interazione del giocatore:

    LineeScopo
    81Imposta lo stesso targetState per SettingsMenu per sincronizzarsi con l'attivazione di SettingsButton.
    85Imposta lo stato di SettingsMenu su menuClosed quando CloseButton è attivato.

    Le linee 51-73 inizializzano e allegano comportamenti a EffectsVolumeSlider e BackgroundVolumeSlider come segue:

    LineeScopo
    52Imposta un riferimento locale al Effects SoundGroup all'interno di SoundService. Un SoundGroup consente di interrelare più Sounds e controllare il volume di ogni suono nel gruppo attraverso la proprietà Volume del gruppo.
    5354Viene dichiarato un riferimento locale effectsVolumeSlider e idratato con la funzione SliderController.hydrate() e il frame EffectsVolumeSlider all'interno di HUDContainer ⟩ SettingsMenu viene referenziato come l'oggetto da idratare. Nota che il secondo parametro di true per FindFirstChild() indica al metodo di cercare ricorsivamente lungo il ramo HUDContainer per localizzare EffectsVolumeSlider.
    55Il valore iniziale del cursore è impostato sul valore attuale di Volume del gruppo Effects, o 0.5 come fallback.
    5660Stabilisce la funzione di callback per applicare le modifiche del valore del cursore al volume del gruppo sonoro Effects.
    6473Essenzialmente come le linee 52-61, eccetto per idratare il frame BackgroundVolumeSlider all'interno di HUDContainer ⟩ SettingsMenu e applicare le modifiche al valore del cursore al volume del gruppo sonoro Background.

Con SettingsScript a posto, l'esperienza ora offre un esempio di UI interattiva completamente operativo che collega un set correlato di oggetti UI all'interazione del giocatore.

© 2026 Roblox Corporation. Roblox, il logo Roblox e Powering Imagination sono tra i nostri marchi registrati e non registrati negli Stati Uniti. e altri paesi.