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.

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:
Abra o modelo Fundamentos de UI - Medidor HUD no Studio.
No menu Teste do Studio, ative o Emulador de Dispositivo.
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.

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.

Para construir o botão de configurações:
Na janela Explorer, localize HUDContainer dentro de StarterGui.

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")
Insira um UIAspectRatioConstraint no botão com propriedades padrão (proporção 1:1 de largura para altura).

Para limitar a altura máxima em pixels do botão, insira um UISizeConstraint e defina seu MaxSize para inf, 44.



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.

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.
Insira um Frame dentro de HUDContainer e renomeie-o para SettingsMenu.

Com SettingsMenu selecionado, defina as seguintes propriedades:
- AnchorPoint = 0.5 (âncora central)
- BackgroundColor3 = 30, 30, 60 (azul marinho)
- BackgroundTransparency = 0.25 (75% opaco)
- Position = 0.5, 0, 0.5, 0 (centro da tela)
- Size = 0.75, 0, 0.75, 0 (75% da largura/altura da área da tela interna)

Insira um UIAspectRatioConstraint em SettingsMenu e defina sua propriedade AspectRatio para 2.5. (2.5:1 de largura para altura).


Insira um modificador UICorner em SettingsMenu e defina seu CornerRadius para 0.1, 0.


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.



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:
Insira um novo Frame no contêiner SettingsMenu e renomeie-o para EffectsVolumeSlider.

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)

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.

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.

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.

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")
Insira um UIAspectRatioConstraint em Icon e deixe suas propriedades como os padrões (1:1 de largura para altura).


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

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.

Com SliderFrame selecionado, defina as seguintes propriedades:
- BackgroundColor3 = 0 (preto)
- BackgroundTransparency = 0.75 (25% opaco)
- LayoutOrder = 1
- Size = 1, 0, 1, 0 (100% da largura/altura do quadro pai)
Insira os seguintes modificadores em SliderFrame:
- UIStroke com sua Color definida para 0, Thickness para 3, e Transparency para 0.25 (contorno preto opaco 75%)

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.

Insira um novo Frame no contêiner SliderFrame e renomeie-o para Handle.

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)
Insira os seguintes modificadores em Handle:
- UIAspectRatioConstraint com suas propriedades padrão (1:1 de largura para altura)
Insira um objeto UIDragDetector em Handle. Este objeto conveniente facilita e incentiva a interação com elementos de interface do usuário 2D.

Defina as seguintes propriedades para o novo UIDragDetector:
- ResponseStyle = Scale (mover por valores de escala da posição do pai do detector)
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:
- Selecione o UIDragDetector.
- Clique na propriedade BoundingUI na janela Propriedades.
- De volta à janela Explorer, clique no pai SliderFrame do manípulo.

A propriedade BoundingUI agora reflete o 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.

Insira um novo Frame no contêiner SliderFrame e renomeie-o para InnerFill.

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



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.

Selecione o objeto EffectsVolumeSlider completo.

Duplique-o (CtrlD ou ⌘D) e renomeie a duplicata para BackgroundVolumeSlider.

Altere a Position da duplicata para 0.5, 0, 0.7, 0 para movê-la abaixo do primeiro controle deslizante.

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



Selecione o quadro InnerFill dentro de SliderFrame e altere sua propriedade BackgroundColor3 para a mesma cor magenta ([255, 0, 125]).



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

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)
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:
Insira um ModuleScript no contêiner ReplicatedStorage e renomeie-o para StatefulObjectController.

Cole o seguinte código dentro do módulo:
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)-- Cria tweens para reutilização para evitar criar novos tweens toda vez que o estado é alteradofor 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("Tentativa de definir %s para o estado desconhecido '%s'", self.object:GetFullName(), stateName))returnendself.currentStateName = stateName-- Certifique-se de que outros tweens não estão em conflitofor _, tween in self.tweens dotween:Cancel()endstateTween:Play()endreturn StatefulObjectControllerExplicação do CódigoLinhas Propósito 6‑10 Define e exporta os tipos Luau para melhorar a autocompletação e linting ao usar este módulo. 12‑33 Funçã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 26‑28 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. 35‑50 Funçã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 45‑47 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.
Insira um ModuleScript no contêiner ReplicatedStorage e renomeie-o para SliderController.

Cole o seguinte código dentro do módulo:
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("Tentativa de hidratar o controle deslizante %s, mas não consegui encontrar o Handle", object:GetFullName()))endlocal innerFill = object:FindFirstChild("InnerFill", true)if not innerFill thenwarn(string.format("Tentativa de hidratar o controle deslizante %s, mas não consegui encontrar o InnerFill", object:GetFullName()))endlocal dragDetector = handle:FindFirstChildWhichIsA("UIDragDetector")if not dragDetector thenwarn(string.format("Tentativa de hidratar o controle deslizante %s, mas não consegui encontrar o UIDragDetector", object:GetFullName()))endlocal self = setmetatable({handle = handle,innerFill = innerFill,dragDetector = dragDetector,value = initialValue or 0.5,onChanged = onChanged,}, SliderController)-- Define o valor inicialself:setValue(self.value)-- Conecta o detector à manipulação do jogadorself.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-- Atualiza a posição do manípulo e o tamanho do quadro interno para corresponderself.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 recentelocal changeSuccess, changeResult = pcall(self.onChanged, clampedValue)if not changeSuccess thenwarn("Erro na chamada de retorno do controle deslizante:", changeResult)endendreturn SliderControllerExplicação do CódigoLinhas Propósito 7‑46 Funçã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 14‑27 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 41‑43 conectam o evento DragContinue do detector à função setValue() do módulo (veja a próxima linha para detalhes). 48‑61 Função usada para definir o valor do controle deslizante. Dentro da função, as linhas 53‑54 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.
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á.

Cole o seguinte código dentro do 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-- Inicializa o botão de configuraçõeslocal 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çõeslocal 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 efeitoslocal 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,})-- Inicializa o controle deslizante de volume de fundolocal 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,})-- Conecta botões à interação do jogadorHUDContainer: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)Consulte as seguintes seções para explorar como o script utiliza os módulos de controle.
Botão de ConfiguraçõesAs linhas 10-27 inicializam e anexam comportamento ao botão de configurações da seguinte forma:
Linhas Propósito 10‑11 Uma 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. 12‑25 Uma 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. 26 O 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:
Linhas Propósito 76‑82 SettingsButton é conectado ao evento Activated da classe GuiButton para chamar uma função anônima. Dentro da função anônima, as linhas 77‑79 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. 83‑86 CloseButton é conectado ao evento Activated para chamar uma função anônima que define o estado de ambos SettingsButton e SettingsMenu como menuClosed. Menu de ConfiguraçõesAs linhas 30-49 inicializam e anexam comportamento ao menu de configurações da seguinte forma:
Linhas Propósito 30‑31 Uma 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. 32‑46 Semelhante 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. 48 O estado inicial do quadro é definido como menuClosed. Mais adiante no script (linhas 76-86), o menu de configurações é vinculado à interação do jogador:
Linhas Propósito 81 Define o mesmo targetState para SettingsMenu para sincronizar com a ativação de SettingsButton. 85 Define o estado de SettingsMenu como menuClosed quando CloseButton é ativado. Controles Deslizantes de VolumeAs linhas 51-73 inicializam e anexam comportamento ao EffectsVolumeSlider e BackgroundVolumeSlider da seguinte forma:
Linhas Propósito 52 Define 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. 53‑54 Uma 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. 55 O valor inicial do controle deslizante é definido como o atual Volume do grupo de som Effects, ou 0.5 como uma alternativa. 56‑60 Estabelece a função de retorno de chamada para aplicar alterações no valor do controle deslizante ao volume do grupo de som Effects. 64‑73 Essencialmente 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.








