Criar UI interativa

*Este conteúdo é traduzido por IA (Beta) e pode conter erros. Para ver a página em inglês, clique aqui.

Um HUD (Heads-Up Display) em seu jogo comumente exibe elementos de UI não interativos, como o medidor de saúde demonstrado em Criar medidores HUD. Além disso, quase todo jogo requer uma UI interativa, como botões que respondem à ativação do jogador, animam quando ativados, fazem transições de menus com outros controles interativos, etc.

Visão do jogo mostrando um botão de configurações e um menu de configurações com controles deslizantes de volume.

Usando Fundamentos de UI - Medidor HUD como um ponto de partida e Fundamentos de UI - Interatividade como um lugar de referência finalizado, este tutorial demonstra:

  • Como posicionar um botão de configurações ao longo da borda superior da tela.
  • Design de um menu de configurações contendo controles deslizantes interativos arrastáveis.
  • Uso de um ModuleScripts para formar módulos de "controlador" para controle extensível de objetos de UI com declarações de estado.
  • Como conectar botões à ativação do jogador para alternar o menu de configurações.
  • Como conectar controles deslizantes de UI arrastáveis para ajustar o volume de efeitos sonoros e ambiente de fundo separadamente.

Ativar o Emulador de Dispositivo

Como observado em Criar medidores HUD, telefones e tablets têm a menor quantidade de espaço na tela, então é importante que seus elementos de UI se encaixem em telas menores e que sejam claramente visíveis para os jogadores. Se você ainda não fez isso, ative o Emulador de Dispositivo no Studio:

  1. Abra o modelo Fundamentos de UI - Medidor HUD no Studio.

  2. No menu Teste do Studio, ative o Emulador de Dispositivo.

  3. Na barra logo acima da visualização principal, selecione uma emulação de telefone, como iPhone X ou Samsung Galaxy A51. Em seguida, defina o tamanho da visualização para Ajustar à Janela para utilizar o máximo de espaço no Studio.

    Opções de configurações do Emulador de Dispositivo indicadas na parte superior da janela de visualização.

Criar o botão de configurações

GuiButtons são elementos interativos da interface do usuário com funcionalidade embutida, como o evento multiplataforma Activated, que é acionado quando o botão é clicado ou tocado. A classe GuiButton se estende a duas variações, TextButton e ImageButton, e este tutorial usa um ImageButton em forma de "engrenagem" para alternar o menu de configurações aberto ou fechado.

Componente Roblox usado para o botão de configurações.

Para construir o botão de configurações:

  1. Na janela Explorer, localize HUDContainer dentro de StarterGui.

    Janela Explorer mostrando o HUDContainer selecionado.
  2. Insira um ImageButton dentro de HUDContainer e renomeie-o para SettingsButton.

    Janela Explorer mostrando um novo ImageButton inserido e renomeado para SettingsButton. Novo ImageButton na visualização.
  3. Com o novo botão selecionado, defina o seguinte na janela Propriedades:

    • AnchorPoint = 0.5, 0.25 (centro horizontal e um quarto superior vertical)
    • BackgroundTransparency = 1 (totalmente transparente)
    • Position = 0.5, 0, 0, 0 (posicionamento no centro superior)
    • Size = 0.1, 0, 0.1, 0 (10% da altura da tela uma vez que a proporção é restringida)
    • Image = rbxassetid://104919049969988 (ID do ativo do símbolo "engrenagem")
  4. Insira um UIAspectRatioConstraint no botão com propriedades padrão (proporção 1:1 de largura para altura).

    Janela Explorer mostrando um novo UIAspectRatioConstraint inserido no botão SettingsButton.
  5. Para limitar a altura máxima em pixels do botão, insira um UISizeConstraint e defina seu MaxSize para inf, 44.

    Janela Explorer mostrando um novo UISizeConstraint inserido no botão SettingsButton.
    Janela de propriedades mostrando os valores esperados para o novo UISizeConstraint.
    Botão de configurações finalizado no centro superior da tela.

Criar o menu de configurações

O novo botão de configurações será programado para alternar um menu de configurações aberto e fechado, dando aos jogadores acesso sob demanda a configurações ou outras informações. Neste tutorial, o menu conterá controles deslizantes interativos para ajustar os níveis de volume do áudio de fundo e dos efeitos sonoros de forma independente.

Componentes básicos usados para o menu de configurações.

Criar o quadro pai

Como observado em Criar medidores HUD, um Frame serve como um contêiner para outros objetos de UI. Todo o menu de configurações será construído com um único quadro pai, tornando-o simples de gerenciar como um objeto com estado que reage à entrada de maneira diferente dependendo do estado atual.

  1. Insira um Frame dentro de HUDContainer e renomeie-o para SettingsMenu.

    Janela Explorer mostrando um novo quadro inserido e renomeado para SettingsMenu.
  2. Com SettingsMenu selecionado, defina as seguintes propriedades:

    Quadro reposicionado, redimensionado e estilizado com fundo azul marinho transparente.
  3. Insira um UIAspectRatioConstraint em SettingsMenu e defina sua propriedade AspectRatio para 2.5. (2.5:1 de largura para altura).

    Janela Explorer mostrando um novo UISizeConstraint inserido no quadro SettingsMenu.
    Janela de propriedades mostrando os valores esperados para o novo UISizeConstraint.
  4. Insira um modificador UICorner em SettingsMenu e defina seu CornerRadius para 0.1, 0.

    Janela Explorer mostrando um novo UICorner inserido no quadro SettingsMenu.
    Janela de propriedades mostrando os valores esperados para o novo modificador UICorner.
  5. Para restringir a largura e altura em pixels de SettingsMenu, insira um UISizeConstraint. Defina seu MaxSize para 800, inf e seu MinSize para 350, 0.

    Janela Explorer mostrando um novo UISizeConstraint inserido no quadro SettingsMenu.
    Janela de propriedades mostrando os valores esperados para o novo UISizeConstraint.
    Quadro estilizado com cantos arredondados.

Construir um controle deslizante

Para permitir que os jogadores ajustem os níveis de volume, o menu de configurações conterá dois widgets de controle deslizante acionados por UIDragDetector, um objeto conveniente que facilita a interação com elementos de interface do usuário 2D.


Para criar um contêiner pai para o primeiro controle deslizante:

  1. Insira um novo Frame no contêiner SettingsMenu e renomeie-o para EffectsVolumeSlider.

    Janela Explorer mostrando um novo quadro inserido no quadro SettingsMenu, renomeado para EffectsVolumeSlider.
  2. Com o quadro EffectsVolumeSlider selecionado, defina as seguintes propriedades:

    • AnchorPoint = 0.5 (âncora central)

    • BackgroundTransparency = 1 (totalmente transparente)

    • Position = 0.5, 0, 0.35, 0 (centro horizontal e 35% da parte superior do contêiner)

    • Size = 0.8, 0, 0.1, 0 (80% da largura do contêiner e 10% de sua altura)

      Quadro vazio inserido para conter elementos do controle deslizante.
  3. Insira um novo UIListLayout em EffectsVolumeSlider. Este modificador de layout é uma maneira poderosa de auto-organizar GuiObjects irmãos em linhas horizontais ou colunas verticais dentro de seu contêiner pai, incluindo a capacidade de aplicar conceitos de flex.

    Janela Explorer mostrando um novo UIListLayout inserido no quadro EffectsVolumeSlider.
  4. Defina as seguintes propriedades para o novo UIListLayout:

    • Padding = 0.06, 0 (6% de preenchimento entre os elementos da lista)
    • FillDirection = Horizontal (arranjo de elementos da esquerda para a direita)
    • HorizontalFlex = Fill (redimensionar elementos horizontalmente para preencher todo o contêiner pai, substituindo sua largura definida)
    • VerticalAlignment = Center (alinhar elementos ao longo de seu centro vertical)

Ícone do controle deslizante

Um ícone simples, incluindo uma nota de áudio e um símbolo de "explosão", ajuda os jogadores a identificar o propósito do controle deslizante quando abrem o menu de configurações.

Ícone indicando o propósito do controle deslizante no menu de configurações.
  1. Insira um ImageLabel no quadro EffectsVolumeSlider e renomeie-o para Icon. Este ícone ajudará os jogadores a entender qual aspecto do jogo o controle deslizante controla.

    Janela Explorer mostrando um ImageLabel inserido no quadro EffectsVolumeSlider.
  2. Com Icon selecionado, defina as seguintes propriedades:

    • BackgroundTransparency = 1 (totalmente transparente)
    • Size = 2.5, 0, 2.5, 0 (250% da altura do quadro pai uma vez que a proporção é restringida)
    • Image = rbxassetid://90019827067389 (ID do ativo da nota de áudio e símbolo de "explosão")
  3. Insira um UIAspectRatioConstraint em Icon e deixe suas propriedades como os padrões (1:1 de largura para altura).

    Janela Explorer mostrando um UIAspectRatioConstraint inserido no ImageLabel. Ícone finalizado no menu de configurações.

Quadro de intervalo

Diretamente à direita do ícone, a parte interativa do controle deslizante deve ser contida dentro de outro Frame.

Tamanho e posição alvo da parte interativa do controle deslizante.
  1. Insira um novo Frame no quadro EffectsVolumeSlider e renomeie-o para SliderFrame. Observe que ele deve ser um irmão direto do modificador de layout UIListLayout.

    Janela Explorer mostrando um quadro filho inserido no quadro EffectsVolumeSlider.
  2. Com SliderFrame selecionado, defina as seguintes propriedades:

  3. Insira os seguintes modificadores em SliderFrame:

    Quadro do controle deslizante posicionado à direita do ícone.

Manípulo interativo

Com o contêiner do controle deslizante construído, você pode agora criar um manípulo arrastável para os jogadores interagirem durante o jogo.

Manípulo interativo do controle deslizante posicionado dentro do quadro de intervalo.
  1. Insira um novo Frame no contêiner SliderFrame e renomeie-o para Handle.

    Janela Explorer mostrando um quadro filho inserido no quadro SliderFrame e renomeado para Handle.
  2. Com Handle selecionado, defina as seguintes propriedades:

    • AnchorPoint = 0.5 (âncora central)
    • Position = 0.5, 0, 0.5, 0 (centro horizontal e vertical do quadro pai)
    • Size = 1.2, 0, 1.2, 0 (120% da altura do quadro pai uma vez que a proporção é restringida)
    • ZIndex = 3 (camada do manípulo visualmente à frente de outros elementos do controle deslizante)
  3. Insira os seguintes modificadores em Handle:

  4. Insira um objeto UIDragDetector em Handle. Este objeto conveniente facilita e incentiva a interação com elementos de interface do usuário 2D.

    Janela Explorer mostrando um UIDragDetector inserido no quadro Handle.
  5. Defina as seguintes propriedades para o novo UIDragDetector:

  6. Para garantir que a faixa de arrasto linear do manípulo seja limitada ao seu contêiner, vincule sua propriedade BoundingUI ao contêiner SliderFrame:

    1. Selecione o UIDragDetector.
    2. Clique na propriedade BoundingUI na janela Propriedades.
    3. De volta à janela Explorer, clique no pai SliderFrame do manípulo.
    Diagrama mostrando o processo de vinculação da propriedade BoundingUI do detector ao contêiner SliderFrame.

    A propriedade BoundingUI agora reflete o contêiner SliderFrame:

    Janela de propriedades mostrando a propriedade BoundingUI do detector vinculada ao contêiner SliderFrame.

Se você testar o jogo agora, poderá arrastar o manípulo para a esquerda e para a direita dentro de seu contêiner pai:

Preenchimento interno

Para indicar mais claramente que o controle deslizante controla uma faixa de 0% a 100%, você pode adicionar um preenchimento interno ao lado esquerdo do contêiner que sincronizará com a posição variável do manípulo.

Porção de preenchimento interno do controle deslizante inserida no SliderFrame.
  1. Insira um novo Frame no contêiner SliderFrame e renomeie-o para InnerFill.

    Janela Explorer mostrando um quadro filho inserido no quadro SliderFrame e renomeado para InnerFill.
  2. Defina as seguintes propriedades para o quadro InnerFill:

    • AnchorPoint = 0, 0.5 (borda esquerda e centro vertical)
    • BackgroundColor3 = [0, 150, 255] (azul combinando com o manípulo do controle deslizante)
    • BackgroundTransparency = 0.35 (65% opaco)
    • Position = 0, 0, 0.5, 0
    • Size = 0.5, 0, 1, 0 (50% de largura e 100% de altura do quadro pai)
    • ZIndex = 2 (camada visualmente à frente do preenchimento/contorno do quadro pai)
  3. Para combinar com a forma de "comprimido" do contêiner pai SliderFrame, insira um modificador UICorner e defina sua propriedade CornerRadius para 0.5, 0.

    Janela Explorer mostrando um modificador UICorner inserido no quadro InnerFill.
    Janela de propriedades mostrando os valores esperados para o novo UICorner.
    Quadro InnerFill estilizado com fundo azul e cantos arredondados.

Duplicar o controle deslizante

Com o primeiro controle deslizante construído, você pode facilmente duplicá-lo e modificar alguns aspectos visuais para indicar outro propósito, neste caso, o nível de volume do áudio de fundo simbolizado por um ícone de notas musicais.

Posição alvo do controle deslizante de áudio de fundo.
  1. Selecione o objeto EffectsVolumeSlider completo.

    Janela Explorer mostrando o EffectsVolumeSlider completo selecionado.
  2. Duplique-o (CtrlD ou D) e renomeie a duplicata para BackgroundVolumeSlider.

    Janela Explorer mostrando o controle deslizante duplicado renomeado para BackgroundVolumeSlider.
  3. Altere a Position da duplicata para 0.5, 0, 0.7, 0 para movê-la abaixo do primeiro controle deslizante.

    BackgroundVolumeSlider posicionado abaixo do EffectsVolumeSlider.
  4. Expanda o ramo de nível superior de BackgroundVolumeSlider, selecione o rótulo de imagem Icon e altere sua propriedade Image para rbxassetid://101125859760167 (ID do ativo do símbolo com notas musicais).

    Janela Explorer mostrando o rótulo Icon dentro de BackgroundVolumeSlider.
    Janela de propriedades mostrando os valores esperados para o rótulo Icon.
    BackgroundVolumeSlider com imagem de ícone modificada.
  5. Expanda o ramo SliderFrameHandle, selecione o modificador UIStroke dentro dele e defina sua propriedade Color para [255, 0, 125] (magenta).

    Janela Explorer mostrando o modificador UIStroke dentro do manípulo de BackgroundVolumeSlider.
    Janela de propriedades mostrando os valores esperados para o modificador UIStroke.
    BackgroundVolumeSlider com imagem de ícone modificada.
  6. Selecione o quadro InnerFill dentro de SliderFrame e altere sua propriedade BackgroundColor3 para a mesma cor magenta ([255, 0, 125]).

    Janela Explorer mostrando o quadro InnerFill dentro do contêiner SliderFrame de BackgroundVolumeSlider.
    Janela de propriedades mostrando os valores esperados para o quadro InnerFill.
    BackgroundVolumeSlider com cor de InnerFill modificada.

Criar o botão de fechar

O elemento final do menu de configurações é um botão de fechar que fornece aos jogadores uma entrada adicional para fechar o menu (o SettingsButton no centro superior servirá ao mesmo propósito).

Menu de configurações com botão de fechar indicado no canto superior direito.
  1. Insira um novo ImageButton no contêiner SettingsMenu e renomeie-o para CloseButton.

    Janela Explorer mostrando um novo ImageButton inserido no SettingsMenu e renomeado para CloseButton. ImageButton vazio posicionado no canto superior esquerdo do menu de configurações.
  2. Com CloseButton selecionado, defina as seguintes propriedades:

    • AnchorPoint = 1, 0 (canto superior direito)
    • BackgroundTransparency = 1 (totalmente transparente)
    • Position = 1, -10, 0, 10 (10 pixels de recuo do canto superior direito)
    • Size = 0.15, 0, 0.15, 0 (15% da altura do quadro uma vez que a proporção é restringida)
    • Image = rbxassetid://5577404210 (ID do ativo do símbolo do botão de fechar)
    • ImageTransparency = 0.25 (75% opaco)
  3. Insira um UIAspectRatioConstraint no botão com propriedades padrão (1:1 de largura para altura).

    Janela Explorer mostrando um UIAspectRatioConstraint inserido no botão CloseButton. Botão de fechar finalizado no canto superior direito do menu de configurações.

Criar os módulos de controle

Uma configuração de módulo de controle extensível torna o gerenciamento de UI interativa mais simplificado do que scripts individuais colocados dentro de cada objeto. ModuleScripts facilitam essa funcionalidade extensível, permitindo que você reutilize código entre scripts em diferentes lados da fronteira cliente-servidor ou no mesmo lado da fronteira.

Controlador de objeto com estado

O seguinte módulo controlador de objeto com estado permite que você anexe comportamento a objetos de UI, como SettingsButton e SettingsMenu, e alternar/fazer transições facilmente entre vários estados. Para criar o módulo:

  1. Insira um ModuleScript no contêiner ReplicatedStorage e renomeie-o para StatefulObjectController.

    Janela Explorer mostrando o módulo StatefulObjectController dentro do contêiner ReplicatedStorage.
  2. Cole o seguinte código dentro do módulo:

    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)
    -- Cria tweens para reutilização para evitar criar novos tweens toda vez que o estado é alterado
    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("Tentativa de definir %s para o estado desconhecido '%s'", self.object:GetFullName(), stateName))
    return
    end
    self.currentStateName = stateName
    -- Certifique-se de que outros tweens não estão em conflito
    for _, tween in self.tweens do
    tween:Cancel()
    end
    stateTween:Play()
    end
    return StatefulObjectController
    LinhasPropósito
    610Define e exporta os tipos Luau para melhorar a autocompletação e linting ao usar este módulo.
    1233Função usada para inicializar e anexar comportamento a um objeto de UI com estado, aceitando um GuiObject como object, uma tabela de estados e seus respectivos dados TweenInfo, e um nome de estado inicial. Dentro desta função, as linhas 2628 constroem Tweens para cada estado, e a linha 30 chama a função setState() do módulo para definir o objeto para o estado inicial.
    3550Função usada para definir/mudar o estado de um objeto com estado. A linha 42 define o currentStateName do objeto para o estado que está sendo definido, as linhas 4547 cancelam quaisquer tweens em execução para evitar conflitos, e a linha 49 executa o(s) tween(s) do estado.

Controlador do controle deslizante

Um módulo adicional inicializa e controla os dois controles deslizantes de volume. Ele também permite que você conecte uma função de retorno de chamada a cada controle deslizante para detectar a interação do jogador com o controle deslizante e aplicar as alterações desejadas no jogo.

  1. Insira um ModuleScript no contêiner ReplicatedStorage e renomeie-o para SliderController.

    Janela Explorer mostrando o módulo SliderController dentro do contêiner ReplicatedStorage.
  2. Cole o seguinte código dentro do módulo:

    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("Tentativa de hidratar o controle deslizante %s, mas não consegui encontrar o Handle", object:GetFullName()))
    end
    local innerFill = object:FindFirstChild("InnerFill", true)
    if not innerFill then
    warn(string.format("Tentativa de hidratar o controle deslizante %s, mas não consegui encontrar o InnerFill", object:GetFullName()))
    end
    local dragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")
    if not dragDetector then
    warn(string.format("Tentativa de hidratar o controle deslizante %s, mas não consegui encontrar o UIDragDetector", object:GetFullName()))
    end
    local self = setmetatable({
    handle = handle,
    innerFill = innerFill,
    dragDetector = dragDetector,
    value = initialValue or 0.5,
    onChanged = onChanged,
    }, SliderController)
    -- Define o valor inicial
    self:setValue(self.value)
    -- Conecta o detector à manipulação do jogador
    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
    -- Atualiza a posição do manípulo e o tamanho do quadro interno para corresponder
    self.handle.Position = UDim2.fromScale(clampedValue, 0.5)
    self.innerFill.Size = UDim2.fromScale(clampedValue, 1)
    -- Executa a função de retorno de chamada do usuário com o valor mais recente
    local changeSuccess, changeResult = pcall(self.onChanged, clampedValue)
    if not changeSuccess then
    warn("Erro na chamada de retorno do controle deslizante:", changeResult)
    end
    end
    return SliderController
    LinhasPropósito
    746Função usada para inicializar e anexar comportamento a um elemento de controle deslizante, aceitando o Frame pai do controle deslizante como object, uma função de retorno de chamada onChanged para processar alterações no controle deslizante, e um valor inicial para a posição do manípulo do controle deslizante. Dentro da função, as linhas 1427 confirmam que os elementos manípulo, preenchimento interno e UIDragDetector do controle deslizante existem. A linha 38 chama a função setValue() do módulo e as linhas 4143 conectam o evento DragContinue do detector à função setValue() do módulo (veja a próxima linha para detalhes).
    4861Função usada para definir o valor do controle deslizante. Dentro da função, as linhas 5354 garantem que a posição do manípulo e o tamanho do preenchimento interno estejam sincronizados, e a linha 57 passa o valor alterado para a função de retorno de chamada para que você possa utilizar o valor conforme necessário.

Criar o script de configurações

Com o botão de configurações e o menu de configurações finalizados, você pode conectar tudo com um único script que utiliza os módulos de controle.

  1. Insira um novo LocalScript dentro de HUDContainer e renomeie-o para SettingsScript para descrever seu propósito. Observe que este script deve estar no mesmo nível (irmão) que SettingsMenu e SettingsButton, os objetos de UI de nível superior que ele gerenciará.

    Janela Explorer mostrando o script SettingsScript dentro do contêiner HUDContainer.
  2. Cole o seguinte código dentro do 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
    -- Inicializa o botão de configurações
    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"
    })
    -- Inicializa o quadro do menu de configurações
    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"
    })
    -- Inicializa o controle deslizante de volume de efeitos
    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,
    })
    -- Inicializa o controle deslizante de volume de fundo
    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,
    })
    -- Conecta botões à interação do jogador
    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. Consulte as seguintes seções para explorar como o script utiliza os módulos de controle.

    As linhas 10-27 inicializam e anexam comportamento ao botão de configurações da seguinte forma:

    LinhasPropósito
    1011Uma referência local settingsButton é declarada e hidratada com a função StatefulObjectController.hydrate(), e o botão SettingsButton dentro de HUDContainer é referenciado como o objeto a ser hidratado.
    1225Uma tabela states é passada com dois estados únicos, menuOpen e menuClosed. Cada estado contém uma transição para declarar (através de um TweenInfo) como o estado particular alcançará suas propriedades alvo definidas na tabela properties. Neste caso, menuOpen declara uma mudança de estado para 45° para a Rotation do botão com um tween de Exponential de ½ segundo, enquanto menuClosed efetivamente restaura o botão para sua rotação padrão de 0.
    26O estado inicial do botão é definido como menuClosed (isso poderia ser definido como qualquer nome de estado dentro da tabela states).

    Mais adiante no script (linhas 76-86), os botões são conectados à interação do jogador para acionar mudanças de estado da UI:

    LinhasPropósito
    7682SettingsButton é conectado ao evento Activated da classe GuiButton para chamar uma função anônima. Dentro da função anônima, as linhas 7779 alternam uma variável targetState entre menuOpen e menuClosed. A linha 80 então chama setState() para definir o estado do botão como targetState e a linha 81 faz o mesmo para SettingsMenu, de modo que ele alterna entre aberto ou fechado com a ativação de SettingsButton.
    8386CloseButton é conectado ao evento Activated para chamar uma função anônima que define o estado de ambos SettingsButton e SettingsMenu como menuClosed.

    As linhas 30-49 inicializam e anexam comportamento ao menu de configurações da seguinte forma:

    LinhasPropósito
    3031Uma referência local settingsMenu é declarada e hidratada com a função StatefulObjectController.hydrate() e o quadro SettingsMenu dentro de HUDContainer é referenciado como o objeto a ser hidratado.
    3246Semelhante ao botão de configurações, uma tabela states é passada com dois estados únicos, menuOpen e menuClosed. Aqui, menuOpen declara uma mudança de estado para UDim2.fromScale(0.5, 0.5) para a Position do quadro com um tween de Bounce de ½ segundo, bem como um estado Visible de true. Em contraste, menuClosed declara uma mudança de estado posicional para UDim2.fromScale(0.5, 0.4) e Visible para false, mas o TweenInfo com duração 0 na linha 41 efetivamente faz com que a mudança de estado ocorra instantaneamente.
    48O estado inicial do quadro é definido como menuClosed.

    Mais adiante no script (linhas 76-86), o menu de configurações é vinculado à interação do jogador:

    LinhasPropósito
    81Define o mesmo targetState para SettingsMenu para sincronizar com a ativação de SettingsButton.
    85Define o estado de SettingsMenu como menuClosed quando CloseButton é ativado.

    As linhas 51-73 inicializam e anexam comportamento ao EffectsVolumeSlider e BackgroundVolumeSlider da seguinte forma:

    LinhasPropósito
    52Define uma referência local ao SoundGroup Effects dentro de SoundService. Um SoundGroup permite que você inter-relacione múltiplos Sounds e controle o volume de cada som no grupo através da propriedade Volume do grupo.
    5354Uma referência local effectsVolumeSlider é declarada e hidratada com a função SliderController.hydrate() e o quadro EffectsVolumeSlider dentro de HUDContainer ⟩ SettingsMenu é referenciado como o objeto a ser hidratado. Observe que o segundo parâmetro de true para FindFirstChild() diz ao método para procurar recursivamente ao longo do ramo HUDContainer para localizar EffectsVolumeSlider.
    55O valor inicial do controle deslizante é definido como o atual Volume do grupo de som Effects, ou 0.5 como uma alternativa.
    5660Estabelece a função de retorno de chamada para aplicar alterações no valor do controle deslizante ao volume do grupo de som Effects.
    6473Essencialmente o mesmo que as linhas 52-61, exceto para hidratar o quadro BackgroundVolumeSlider dentro de HUDContainer ⟩ SettingsMenu e aplicar alterações no valor do controle deslizante ao volume do grupo de som Background.

Com SettingsScript em vigor, o jogo agora oferece um exemplo de UI interativa totalmente operacional que vincula um conjunto relacionado de objetos de UI à interação do jogador.

©2026 Roblox Corporation, Roblox, o logotipo Roblox e Powering Imagination estão entre nossas marcas registradas e não registradas nos EUA e em outros países.