Tutoriais intermediários

Criar medidores HUD

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

Um HUD ou Heads-Up Display é um conjunto de elementos de interface que estão sempre visíveis ou acessíveis durante a jogabilidade, como exibições de pontuação, medidores de saúde e botões de menu. Incluir um HUD é essencial para a maioria das experiências, pois ele exibe informações que ajudam os jogadores a serem bem-sucedidos em seus objetivos de jogabilidade.

Um elemento comum do HUD é um medidor de saúde com um ícone à esquerda, que pode ser adaptado em uma barra de cronômetro, barra de progresso ou similar.

Visão do jogo mostrando medidor de saúde personalizado na região superior direita.

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

  • Configuração e uso do Emulador de Dispositivos para testar seu design em várias telas emuladas.
  • Uso de StarterGui como um container de design e armazenamento.
  • Como posicionar/dimensionar elementos da UI em torno de controles Roblox integrados e recortes/ilhas de dispositivos, como o recorte da câmera em telefones modernos.
  • Como substituir o medidor de saúde padrão do Roblox pelo seu próprio medidor e conectá-lo ao nível de saúde do personagem.
  • Como animar a parte central do medidor de saúde e definir sua cor entre cinco pontos-chave de gradiente de cores (vermelho, laranja, amarelo, limão, verde).

Habilitar o Emulador de Dispositivos

Roblox é inerentemente multiplataforma, já que os jogadores podem descobrir e entrar em experiências em seus telefones ou tablets e, em seguida, continuar de onde pararam em seu PC ou console. Dispositivos móveis (telefones e tablets) têm a menor quantidade de espaço na tela, portanto, é importante que seus elementos de interface se encaixem em telas menores e que sejam claramente visíveis para os jogadores.

A melhor maneira de testar designs de UI em várias plataformas é o Emulador de Dispositivos do Studio. Esta ferramenta oferece uma seleção pré-definida de dispositivos e permite que você adicione suas próprias predefinições personalizadas.

  1. Abra o template Hazardous Space Station no Studio.

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

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

    Opções de configurações do Emulador de Dispositivos indicadas na parte superior da janela da viewport.

Criar um container de tela

Um container ScreenGui contém objetos de UI (GuiObjects) para exibir na tela de um jogador (neste tutorial, a totalidade do medidor de saúde). Para exibir um ScreenGui e seus objetos filhos para cada jogador que entra na experiência, coloque-o dentro do container StarterGui. Quando um jogador entra e seu personagem aparece pela primeira vez, o ScreenGui e seu conteúdo se clonam no container PlayerGui para aquele jogador, localizado dentro do container Players.

Diagrama de como um ScreenGui se clona de StarterGui para a PlayerGui de um jogador

Para inserir um ScreenGui vazio:

  1. Na janela Explorer, localize o container StarterGui.

    Janela Explorer mostrando o container StarterGui.
  2. Passe o mouse sobre o container, clique no botão ⊕ e insira um ScreenGui.

    ScreenGui inserido no container StarterGui.
  3. Renomeie o novo container para HUDContainer para refletir seu propósito.

    ScreenGui renomeado para HUDContainer.

Utilize áreas seguras

Os telefones modernos aproveitam toda a tela, mas geralmente incluem recortes, cortes e outros elementos que ocupam espaço na tela. Cada experiência Roblox também inclui os controles da barra superior para acesso rápido ao menu principal, chat, placar e mais.

Dispositivo móvel mostrando os botões da barra superior do Roblox e recorte do dispositivo.

Para garantir que os jogadores possam ver e acessar toda a UI sem obstruções, Roblox fornece a propriedade ScreenInsets que controla a área segura para o conteúdo de um ScreenGui. Cada objeto de UI que você posiciona dentro de um ScreenGui é relativo aos limites do inseto.

Dispositivo móvel mostrando a área segura da interface principal.

Enquanto o padrão de CoreUISafeInsets garante que todos os objetos de UI fiquem livres de interfaces do Roblox e cortes do dispositivo, DeviceSafeInsets pode ser uma opção melhor para utilizar espaço na tela limitado, conforme ilustrado abaixo.

ScreenInsets definido como CoreUISafeInsets.
  1. Na janela Explorer, selecione HUDContainer.

    Janela Explorer mostrando o HUDContainer selecionado.
  2. Na janela Propriedades, defina a propriedade ScreenInsets para DeviceSafeInsets.

    ScreenInsets definido como DeviceSafeInsets na janela de Propriedades.

Definir espaçamento nas bordas

Com ScreenInsets definido como DeviceSafeInsets, o conteúdo pode agora se estender diretamente até a borda superior física da tela. No entanto, uma pequena quantidade de preenchimento pode ajudar a empurrar o medidor de saúde (e outros objetos dentro do container) levemente para longe das bordas da tela para uma aparência mais limpa e para evitar que sejam cortados.

Container de tela com preenchimento ao redor de todas as bordas.

Uma maneira de aplicar preenchimento a um container de UI é por meio da inserção de um modificador UIPadding:

  1. Insira um modificador UIPadding no HUDContainer.

    HUDContainer com modificador UIPadding inserido.
  2. Com o novo objeto UIPadding selecionado, insira um valor de 0, 16 para todas as bordas do container (PaddingBottom, PaddingLeft, PaddingRight, PaddingTop). Isso aplica um preenchimento de 16 pixels ao redor do container, independentemente da resolução da tela.

    Janela de Propriedades mostrando o modificador UIPadding com 0, 16 definido para todas as bordas.

Construir o medidor de saúde

Com o container de tela configurado, você pode começar a construir o medidor de saúde usando objetos de UI do Roblox, como frames e um rótulo de imagem.

Componentes básicos usados para o medidor de saúde.

Criar o frame pai

Similar a aplicativos de design como Figma e Photoshop, um Frame no Roblox serve como um container para outros objetos de UI. Para este tutorial, todo o medidor de saúde será contido em um único frame pai, tornando mais simples reposicionar em vários layouts de HUD.

  1. Insira um Frame no HUDContainer. O novo frame aparece no canto superior esquerdo como um quadrado branco vazio.

    Novo frame na viewport.
  2. Renomeie a nova instância do frame para MeterBar.

    Novo frame inserido e renomeado para MeterBar.

Posicionar o frame

No Roblox, a posição de um objeto de UI é representada por um conjunto de coordenadas UDim2 contendo valores de Scale e Offset para os eixos X e Y:

  • Os valores de Scale representam uma porcentagem do tamanho do container ao longo do eixo correspondente, aditivo de quaisquer valores de Offset.
  • Os valores de Offset representam quantos pixels deslocar o objeto ao longo do eixo correspondente, aditivo de quaisquer valores de Scale.

Para posicionar um objeto de UI no canto superior direito do container da tela, Scale é a melhor abordagem, porque um valor de X de 1 (100%) representa a borda direita do container, independentemente do tamanho físico em pixels da tela. De forma semelhante, um valor de escala de Y de 0 (0%) representa a borda superior do container.

Intervalos de escala para os eixos X e Y de um container.

Além disso, você precisará definir um ponto de âncora superior direita para o frame pai para definir seu ponto de origem. Valores aceitáveis estão entre 0 e 1, relativos ao tamanho do objeto, então um valor de âncora de 1, 0 coloca o ponto de âncora do frame em seu canto superior direito.

Ponto de âncora do frame em seu canto superior direito.
  1. Na janela Explorer, selecione o frame MeterBar que você inseriu anteriormente.

    Janela Explorer mostrando o frame MeterBar selecionado.
  2. Na janela Propriedades, insira 1, 0, 0, 0 para Position e pressione Enter. O Studio adicionará automaticamente os colchetes para formar o UDim2 de {1, 0},{0, 0}.

  3. Insira 1, 0 para a propriedade AnchorPoint. O frame agora deve estar posicionado no canto superior direito da área segura do dispositivo, levemente recuado da borda em resultado do preenchimento.

    Frame reposicionado no canto superior direito do container.

Redimensionar o frame

Assim como a posição, o Size de um objeto de UI é representado por um conjunto de coordenadas UDim2 contendo valores de Scale e Offset para os eixos X e Y.

Por padrão, o tamanho do novo frame é {0, 100},{0, 100}, significando 100 pixels tanto de largura (X) quanto de altura (Y). Enquanto um valor estrito em pixels é útil em certos casos, muitos elementos de UI escalam mais responsivamente em várias telas quando definidos como uma porcentagem do tamanho total do container da tela.

  1. Com o frame MeterBar selecionado, acesse a janela Propriedades e navegue até a propriedade Size.

  2. Insira um valor de 0.35, 0, 0.05, 0 para definir um tamanho percentual de 35% de largura e 5% de altura, sem deslocamentos de pixel adicionais.

    Frame redimensionado para 35% de largura e 5% de altura.

Estilizar o frame

Por padrão, Frames são preenchidos em branco sólido. O medidor de saúde final deve ter um preenchimento mais escuro e levemente opaco, além de um contorno escuro, para que se destaque melhor em fundos claros e escuros.

Frame estilizado com opacidade, borda e cantos arredondados.
  1. Com o frame MeterBar selecionado, insira 0 para a propriedade BackgroundColor3. O Studio converterá automaticamente para o valor RGB de [0, 0, 0].

  2. Insira 0.75 para a propriedade BackgroundTransparency. No Roblox, a transparência varia de 0 para totalmente opaco a 1 para totalmente transparente, então 0.75 equivale a 25% de opacidade em outros aplicativos como Figma ou Photoshop.

    Frame reestilizado com fundo escuro e 25% de opacidade.
  3. Insira um objeto UIStroke, um poderoso modificador de UI que adiciona um traço personalizável ao frame.

    Janela Explorer mostrando o frame MeterBar com um modificador UIStroke filho.
  4. Com o novo UIStroke selecionado, defina as seguintes propriedades:

    Frame reestilizado com um modificador UIStroke.

Para finalizar a estilização do frame do medidor, você pode arredondar os cantos para formar uma forma de "pílula" em vez de um retângulo afiado.

  1. Insira uma instância UICorner no frame MeterBar.

    Janela Explorer mostrando o frame MeterBar com um modificador UICorner filho.
  2. Com o novo modificador UICorner selecionado, defina a propriedade CornerRadius para 0.5, 0. Usar um valor de escala de 0.5 (50%) em vez de um valor em pixels é especialmente conveniente para a barra de medidor, pois garante uma curva totalmente arredondada, não importando quão alta ou larga a container se torne.

    Cantos do frame arredondados com um modificador UICorner.

Criar o preenchimento interno

Agora que o frame que contém o medidor de saúde está completo, você pode adicionar uma porção de preenchimento interno para representar a saúde variável do personagem. Como precisa apenas ser uma região preenchida sólida, um Frame sub-filho dentro do frame pai é apropriado.

Preenchimento interno adicionado ao frame pai para representar a saúde variável do personagem.
  1. Insira um Frame filho no frame MeterBar.

  2. Renomeie a nova instância do frame para InnerFill.

    Janela Explorer mostrando o frame pai MeterBar com um frame filho nomeado InnerFill.
  3. Com InnerFill selecionado, defina as seguintes propriedades:

    Como os filhos de frames são posicionados e dimensionados em relação ao seu pai, o uso de escala faz com que o frame interno preencha toda a largura e altura do pai, começando da borda esquerda do pai.

    Frame do preenchimento interno reposicionado e redimensionado para preencher todo o frame pai.
  4. Para combinar a forma de "pílula" do frame pai, insira um UICorner adicional no InnerFill.

    Janela Explorer mostrando o frame InnerFill com um modificador UICorner filho.
  5. Com o novo modificador UICorner selecionado, defina sua propriedade CornerRadius para 0.5, 0 para combinar com a forma de "pílula" do frame pai MeterBar.

    Cantos do frame de preenchimento interno arredondados com um modificador UICorner.
  6. Para melhor representar que um medidor cheio indica boa saúde, selecione InnerFill e defina sua propriedade BackgroundColor3 para [0, 225, 50] (em uma tarefa futura, você programará esta cor para mudar com base na saúde real).

    Frame de preenchimento interno colorido de verde para representar boa saúde.

Adicionar o ícone

Para indicar mais claramente o propósito do medidor, você pode adicionar um rótulo de imagem ao lado esquerdo, neste caso, um coração vermelho que comumente simboliza saúde ou vida.

Rótulo de imagem de coração adicionado para indicar mais claramente um medidor de saúde.
  1. Insira um ImageLabel no frame MeterBar. Este objeto permite que você aplique um ativo de imagem 2D que foi carregado como um decalque no Roblox.

  2. Renomeie a nova instância do rótulo para Icon.

    Janela Explorer mostrando o frame MeterBar com um rótulo ImageLabel filho.
  3. Com Icon selecionado, defina sua propriedade ZIndex para 2. Embora os objetos de UI recém-inseridos sempre se sobreponham aos objetos inseridos anteriormente, essa mudança garante que o ícone sempre seja exibido à frente dos elementos do frame do medidor.

    Janela de Propriedades mostrando o ZIndex do ImageLabel definido como 2.
  4. Localize a propriedade Image do ícone e insira rbxassetid://91715286435585, a referência a uma imagem de coração pré-carregada (se desejar, você pode importar sua própria imagem e usar seu ID de ativo).

    Rótulo de imagem de coração adicionado ao frame MeterBar.
  5. Para garantir que o ícone ImageLabel sempre mantenha uma proporção de aspecto de 1:1, insira um UIAspectRatioConstraint. Embora essa restrição tenha propriedades personalizáveis para controlar a proporção de aspecto, você pode deixar seus valores padrão intactos.

    Janela Explorer mostrando o ImageLabel com uma restrição UIAspectRatioConstraint filho.
  6. Com Icon selecionado, finalize a aparência e a posição alterando as seguintes propriedades:

    Rótulo de imagem de coração reposicionado e redimensionado com preenchimento de fundo tornado transparente.

Restringir o tamanho

Embora uma altura de escala de 0.05 (5%) pareça boa em telas de telefones modernos e monitores de jogos que têm uma proporção de aspecto de 16:9 ou mais, o medidor pode parecer ligeiramente alto demais em telas de tablets e telefones mais antigos. Você pode verificar isso emulando um tablet como o iPad 7ª Geração usando o Emulador de Dispositivos.

Emulador de Dispositivos configurado para emular um dispositivo tablet. Emulação em dispositivo tablet com barra de medidor mais alta do que desejado.

Para manter a altura da barra de medidor mais consistente entre telas mais largas, você pode aplicar um UISizeConstraint para limitar a altura máxima em pixels.

  1. Insira um UISizeConstraint no frame MeterBar.

    Janela Explorer mostrando o frame MeterBar com um modificador UISizeConstraint filho.
  2. Com a nova restrição selecionada, defina sua propriedade MaxSize como inf, 20 para restringir sua altura a 20 pixels enquanto não impõe restrição de largura.

    Janela de Propriedades mostrando o MaxSize da UISizeConstraint definido para inf, 20.

Agora, a barra de medidor mantém uma altura mais consistente entre telas mais largas e mais altas.

Emulação em telefone.

Substituir o medidor de saúde padrão

As experiências do Roblox incluem um medidor de saúde padrão que se torna visível quando os personagens recebem dano. Se você mantiver o medidor padrão visível, ele irá duplicar e potencialmente sobrepor o medidor personalizado.

Medidor de saúde padrão sobrepondo e duplicando o medidor de saúde personalizado.

Desativar o medidor padrão

Para desativar o medidor padrão de saúde, você usará um script do cliente (LocalScript) dentro de StarterPlayerScripts que chama StarterGui:SetCoreGuiEnabled().

  1. Na janela Explorer, expanda o container StarterPlayer e localize o container StarterPlayerScripts dentro dele.

    Janela Explorer mostrando o container StarterPlayerScripts dentro do container StarterPlayer.
  2. Insira um novo LocalScript no container e renomeie-o para HideDefaultHealthMeter para descrever seu propósito. Scripts dentro de StarterPlayerScripts são executados automaticamente quando o jogador local entra em uma experiência, tornando este container ideal para executar um script que oculta permanentemente o medidor padrão.

    Janela Explorer mostrando o novo script do cliente HideDefaultHealthMeter dentro do container StarterPlayerScripts.
  3. Quando você insere um novo script, ele se abre automaticamente em uma nova aba do editor de scripts (se não abrir, clique duas vezes no script na janela Explorer).

    Cole o seguinte código dentro do script HideDefaultHealthMeter:

    HideDefaultHealthMeter

    local StarterGui = game:GetService("StarterGui")
    -- Oculta o medidor de saúde padrão
    StarterGui:SetCoreGuiEnabled(Enum.CoreGuiType.Health, false)
    LinhaPropósito
    1Obtém uma referência a um serviço, StarterGui, que representa o mesmo container onde você criou o medidor de saúde personalizado e cujo conteúdo se clona no container PlayerGui para cada jogador que ingressa na experiência.
    4Chama o método SetCoreGuiEnabled() do serviço e instruí o medidor de saúde padrão a ser desativado (false).

Se você testar a experiência agora e receber dano, notará que o medidor padrão está desativado e oculto (você programará o medidor personalizado para refletir as mudanças de saúde na próxima seção).

Medidor de saúde padrão desativado.

Ouvir mudanças na saúde

Todos os modelos de personagens padrão do Roblox contêm uma classe Humanoid que fornece comportamentos e funcionalidades especiais ao personagem, como definir sua velocidade de caminhada/corrida e gerenciar sua saúde. As mudanças na Health no servidor replicam para o cliente de cada jogador e você pode detectar essas mudanças para atualizar tanto o tamanho quanto a cor do medidor de saúde personalizado.

  1. Na janela Explorer, localize o container StarterCharacterScripts dentro de StarterPlayer.

    Janela Explorer mostrando o container StarterCharacterScripts dentro do container StarterPlayer.
  2. Insira um novo LocalScript no container e renomeie-o para UpdateCustomMeter para descrever seu propósito. Scripts dentro de StarterCharacterScripts são executados automaticamente cada vez que o personagem do jogador aparece, tornando este container ideal para executar um script que redefinirá completamente o medidor de saúde em cada renascimento.

    Janela Explorer mostrando o novo script do cliente UpdateCustomMeter dentro do container StarterCharacterScripts.
  3. Na janela do editor para o script UpdateCustomMeter, cole o seguinte código:

    UpdateCustomMeter

    local Players = game:GetService("Players")
    -- Referência ao jogador local, personagem e humanoide
    local player = Players.LocalPlayer
    local character = player.Character
    local humanoid = character:WaitForChild("Humanoid")
    -- Referência ao frame interno do medidor
    local playerGui = player:WaitForChild("PlayerGui")
    local meterBarInner = playerGui.HUDContainer.MeterBar.InnerFill
    -- Cores da sequência de gradiente (vermelho, laranja, amarelo, limão, verde)
    local gradient = {
    Color3.fromRGB(225, 50, 0),
    Color3.fromRGB(255, 100, 0),
    Color3.fromRGB(255, 200, 0),
    Color3.fromRGB(150, 225, 0),
    Color3.fromRGB(0, 225, 50)
    }
    -- Função para obter a cor na sequência de gradiente a partir de um ponto fracionário
    local function getColorFromSequence(fraction: number): Color3
    -- Cada cor no gradiente define o início e/ou fim de uma seção
    local numSections = #gradient - 1
    -- Cada seção representa uma parte de 1
    local sectionSize = 1 / numSections
    -- Determine em qual seção a fração solicitada se encontra
    local sectionStartIndex = 1 + math.clamp(fraction, 0, 1) // sectionSize
    -- Obtenha as cores no início e no fim da seção
    local sectionColorStart = gradient[sectionStartIndex]
    local sectionColorEnd = gradient[sectionStartIndex + 1] or sectionColorStart
    -- Normalizar a fração para ser um número de 0 a 1 dentro da seção
    local fractionOfSection = math.clamp(fraction, 0, 1) % sectionSize / sectionSize
    -- Lerp entre o começo e o fim com base na fração normalizada
    return sectionColorStart:Lerp(sectionColorEnd, fractionOfSection)
    end
    local function onHealthChanged()
    -- Calcule a nova saúde como porcentagem do máximo
    local healthFraction = math.max(0, humanoid.Health / humanoid.MaxHealth)
    -- Defina o bar para novos alvos de tamanho/cor
    meterBarInner.Size = UDim2.new(healthFraction, 0, 1, 0)
    meterBarInner.BackgroundColor3 = getColorFromSequence(healthFraction)
    end
    -- Ouve mudanças na saúde do humanoide
    humanoid.HealthChanged:Connect(onHealthChanged)
    -- Inicialmente define (ou redefine) o tamanho/cor da barra para a saúde atual
    onHealthChanged()
    LinhasPropósito
    46Obtém referências ao Player local, seu modelo de Character e a classe Humanoid dentro dele.
    910Obtém uma referência ao objeto InnerFill do medidor que deve ser redimensionado e colorido à medida que a saúde do personagem muda.
    1319Declara um array de cinco cores (vermelho, laranja, amarelo, limão, verde) para recolorir o medidor em vários pontos; por exemplo, verde para 100% de saúde, amarelo para 50%, vermelho para 0% ou uma mistura em qualquer fração entre os pontos-chave.
    2241Função auxiliar que retorna a mistura de cor entre quaisquer dos pontos chave de cor do gradiente.
    4350Função que lida com quaisquer mudanças na saúde. Aqui, calcula a nova saúde como uma porcentagem da MaxHealth do personagem, redimensiona InnerFill para essa porcentagem de escala e muda sua cor para a cor retornada pela função getColorFromSequence().
    53A conexão de evento principal que detecta as mudanças de Health replicadas do servidor e chama a função onHealthChanged().
    56Inicialmente (quando o personagem aparece ou renasce) chama a função onHealthChanged() para dimensionar e colorir InnerFill na porcentagem correta. Normalmente, isso será a largura total e verde.

Se você testar a experiência agora, notará que o medidor personalizado atualiza corretamente tanto o tamanho quanto a cor à medida que o personagem recebe dano:

Animar a barra do medidor

Para adicionar um nível extra de polimento ao medidor personalizado, você pode animar as mudanças de saúde através de tweening, alterando gradualmente o tamanho e a cor da barra do medidor ao longo de ½ segundo.

  1. Acesse a aba do editor de scripts para o script UpdateCustomMeter que você editou anteriormente.

  2. Selecione todas as linhas (CtrlA ou A) e, em seguida, cole sobre elas (CtrlV ou V) o seguinte código:

    UpdateCustomMeter

    local Players = game:GetService("Players")
    local TweenService = game:GetService("TweenService")
    -- Referência ao jogador local, personagem e humanoide
    local player = Players.LocalPlayer
    local character = player.Character
    local humanoid = character:WaitForChild("Humanoid")
    -- Propriedades de tween
    local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)
    -- Referência ao frame interno do medidor
    local playerGui = player:WaitForChild("PlayerGui")
    local meterBarInner = playerGui.HUDContainer.MeterBar.InnerFill
    -- Cores da sequência de gradiente (vermelho, laranja, amarelo, limão, verde)
    local gradient = {
    Color3.fromRGB(225, 50, 0),
    Color3.fromRGB(255, 100, 0),
    Color3.fromRGB(255, 200, 0),
    Color3.fromRGB(150, 225, 0),
    Color3.fromRGB(0, 225, 50)
    }
    -- Função para obter a cor na sequência de gradiente a partir de um ponto fracionário
    local function getColorFromSequence(fraction: number): Color3
    -- Cada cor no gradiente define o início e/ou fim de uma seção
    local numSections = #gradient - 1
    -- Cada seção representa uma parte de 1
    local sectionSize = 1 / numSections
    -- Determine em qual seção a fração solicitada se encontra
    local sectionStartIndex = 1 + math.clamp(fraction, 0, 1) // sectionSize
    -- Obtenha as cores no início e no fim da seção
    local sectionColorStart = gradient[sectionStartIndex]
    local sectionColorEnd = gradient[sectionStartIndex + 1] or sectionColorStart
    -- Normalizar a fração para ser um número de 0 a 1 dentro da seção
    local fractionOfSection = math.clamp(fraction, 0, 1) % sectionSize / sectionSize
    -- Lerp entre o começo e o fim com base na fração normalizada
    return sectionColorStart:Lerp(sectionColorEnd, fractionOfSection)
    end
    local function onHealthChanged()
    -- Calcule a nova saúde como porcentagem do máximo
    local healthFraction = math.max(0, humanoid.Health / humanoid.MaxHealth)
    -- Tween a barra para novos alvos de tamanho/cor
    local tweenGoal = {
    Size = UDim2.new(healthFraction, 0, 1, 0),
    BackgroundColor3 = getColorFromSequence(healthFraction)
    }
    local meterBarTween = TweenService:Create(meterBarInner, tweenInfo, tweenGoal)
    meterBarTween:Play()
    end
    -- Ouve mudanças na saúde do humanoide
    humanoid.HealthChanged:Connect(onHealthChanged)
    -- Inicialmente define (ou redefine) o tamanho/cor da barra para a saúde atual
    onHealthChanged()
    LinhasPropósito
    2Obtém uma referência a TweenService para implementar a funcionalidade de tweening dentro do script.
    10Cria um construtor TweenInfo que define a duração pretendida do tween, o estilo de easing e a direção de easing.
    5257Em vez de simplesmente definir o tamanho e a color de forma como na versão anterior, declara uma tabela tweenGoal com o tamanho/cor alvo, cria um novo tween usando os parâmetros tweenInfo e tweenGoal e reproduz o novo tween.

Se você testar a experiência agora, notará que o medidor personalizado faz tweening entre cada mudança na saúde:

Adicionar um efeito de dano

O sistema de medição de saúde padrão inclui um leve e sutil tom vermelho nas bordas da tela quando o personagem recebe dano. Ao desativar o medidor padrão, esse efeito é removido, mas você pode substituí-lo pela sua própria implementação.

  1. Acesse a aba do editor de scripts para o script UpdateCustomMeter que você editou anteriormente.

  2. Selecione todas as linhas e cole sobre elas com o seguinte código:

    UpdateCustomMeter

    local Workspace = game:GetService("Workspace")
    local Players = game:GetService("Players")
    local TweenService = game:GetService("TweenService")
    -- Referência ao jogador local, personagem e humanoide
    local player = Players.LocalPlayer
    local character = player.Character
    local humanoid = character:WaitForChild("Humanoid")
    -- Propriedades de tween
    local tweenInfo = TweenInfo.new(0.5, Enum.EasingStyle.Exponential, Enum.EasingDirection.Out)
    -- Variável para armazenar/cache a saúde do personagem
    local cachedHealth = humanoid.Health / humanoid.MaxHealth
    -- Obtenha (ou crie nova) correção de cor dentro da câmera do jogador
    local colorCorrection = Workspace.CurrentCamera:FindFirstChildWhichIsA("ColorCorrectionEffect") or Instance.new("ColorCorrectionEffect", Workspace.CurrentCamera)
    colorCorrection.Name = "DamageColorEffect"
    -- Referência ao frame interno do medidor
    local playerGui = player:WaitForChild("PlayerGui")
    local meterBarInner = playerGui.HUDContainer.MeterBar.InnerFill
    -- Cores da sequência de gradiente (vermelho, laranja, amarelo, limão, verde)
    local gradient = {
    Color3.fromRGB(225, 50, 0),
    Color3.fromRGB(255, 100, 0),
    Color3.fromRGB(255, 200, 0),
    Color3.fromRGB(150, 225, 0),
    Color3.fromRGB(0, 225, 50)
    }
    -- Função para obter a cor na sequência de gradiente a partir de um ponto fracionário
    local function getColorFromSequence(fraction: number): Color3
    -- Cada cor no gradiente define o início e/ou fim de uma seção
    local numSections = #gradient - 1
    -- Cada seção representa uma parte de 1
    local sectionSize = 1 / numSections
    -- Determine em qual seção a fração solicitada se encontra
    local sectionStartIndex = 1 + math.clamp(fraction, 0, 1) // sectionSize
    -- Obtenha as cores no início e no fim da seção
    local sectionColorStart = gradient[sectionStartIndex]
    local sectionColorEnd = gradient[sectionStartIndex + 1] or sectionColorStart
    -- Normalizar a fração para ser um número de 0 a 1 dentro da seção
    local fractionOfSection = math.clamp(fraction, 0, 1) % sectionSize / sectionSize
    -- Lerp entre o começo e o fim com base na fração normalizada
    return sectionColorStart:Lerp(sectionColorEnd, fractionOfSection)
    end
    local function onHealthChanged()
    -- Calcule a nova saúde como porcentagem do máximo
    local healthFraction = math.max(0, humanoid.Health / humanoid.MaxHealth)
    -- Tween a barra para novos alvos de tamanho/cor
    local tweenGoal = {
    Size = UDim2.new(healthFraction, 0, 1, 0),
    BackgroundColor3 = getColorFromSequence(healthFraction)
    }
    local meterBarTween = TweenService:Create(meterBarInner, tweenInfo, tweenGoal)
    meterBarTween:Play()
    -- Mostre o efeito de dano se a nova saúde for menor que a saúde cache
    if healthFraction < cachedHealth then
    -- Cache o novo valor de saúde
    cachedHealth = healthFraction
    -- Defina a correção de cor como vermelho como o tom inicial antes do tweening
    colorCorrection.TintColor = Color3.fromRGB(255, 25, 25)
    colorCorrection.Saturation = 2.5
    -- Tween o tom de volta para branco (neutro e sem mudança de tom do normal)
    local colorCorrectionTweenGoal = {
    TintColor = Color3.fromRGB(255, 255, 255),
    Saturation = 0
    }
    local colorCorrectionTween = TweenService:Create(colorCorrection, tweenInfo, colorCorrectionTweenGoal)
    colorCorrectionTween:Play()
    end
    end
    -- Ouve mudanças na saúde do humanoide
    humanoid.HealthChanged:Connect(onHealthChanged)
    -- Inicialmente define (ou redefine) o tamanho/cor da barra para a saúde atual
    onHealthChanged()
    LinhasPropósito
    14Define uma referência de placeholder (cachedHealth) para rastrear a quantidade de saúde do personagem entre mudanças, para que você possa comparar se uma mudança é menor (dano).
    1718Na aparição inicial do personagem, cria um novo ColorCorrectionEffect dentro da Camera atual do jogador ou obtém uma referência à mesma instância em renascimentos posteriores. Ao parentar esse efeito de pós-processamento à câmera do jogador, ele se aplica apenas à tela local deles, não à tela de todos os jogadores no servidor.
    6883Primeiro realiza uma verificação condicional para confirmar que a mudança de saúde é menor que o valor de cachedHealth, indicando dano; se sim, define cachedHealth para o novo valor. Em seguida, define o tom da ColorCorrectionEffect para [255, 25, 25] (vermelho) com maior saturação e, por fim, tween o tom de volta para o padrão neutro branco ([255, 255, 255]) sem saturação.

Se você testar a experiência agora, notará que a tela pisca brevemente de vermelho sempre que o personagem recebe dano:

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