HUD básico com UMG: feedback de pontuação e interação

Capítulo 10

Tempo estimado de leitura: 8 minutos

+ Exercício

O que é HUD com UMG e por que usar

HUD (Heads-Up Display) é a camada de interface que dá feedback imediato ao jogador: pontuação, vida/stamina, mensagens contextuais e indicadores. No Unreal, a forma mais comum de criar HUD é com UMG (Unreal Motion Graphics), construindo um Widget Blueprint e adicionando-o à tela no início do jogo.

Neste capítulo você vai montar um HUD básico com três elementos: pontuação, mensagem contextual de interação (ex.: “Pressione E para Interagir”) e uma barra simples (vida ou stamina). O foco é atualizar a UI de forma eficiente, evitando “bindings” pesados quando possível, preferindo atualização por eventos.

Estrutura recomendada (quem cria e quem atualiza)

  • Widget (WBP_HUD): só exibe dados e recebe comandos para atualizar textos/barras.
  • Player Controller ou Character: cria o widget e mantém uma referência; dispara atualizações quando algo muda.
  • Sistemas de gameplay (pontuação, stamina, interação): emitem eventos/dispatchers ou chamam funções no widget via referência.

Essa separação evita que o Widget fique “caçando” informações a cada frame e reduz acoplamento.

Criando o Widget UMG (WBP_HUD)

1) Criar o Widget Blueprint

  • No Content Browser: Add > User Interface > Widget Blueprint
  • Nome: WBP_HUD
  • Abra o Designer.

2) Montar o layout (Designer)

Uma composição simples e funcional:

  • Pontuação no canto superior esquerdo
  • Mensagem contextual central inferior
  • Barra (vida/stamina) no canto inferior esquerdo

No Designer:

Continue em nosso aplicativo e ...
  • Ouça o áudio com a tela desligada
  • Ganhe Certificado após a conclusão
  • + de 5000 cursos para você explorar!
ou continue lendo abaixo...
Download App

Baixar o aplicativo

  • Adicione um Canvas Panel (geralmente já vem como raiz).
  • Score: adicione um Horizontal Box ancorado no topo esquerdo. Dentro, um Image (ícone opcional) e um TextBlock para o valor. Marque o TextBlock como Is Variable e renomeie para TXT_Score.
  • Mensagem contextual: adicione um Border ou SizeBox ancorado no centro inferior. Dentro, um TextBlock marcado como variável, renomeie para TXT_Context. Comece com texto vazio e configure alinhamento central.
  • Barra: adicione um ProgressBar ancorado no inferior esquerdo. Marque como variável e renomeie para PB_Stamina (ou PB_Health).

3) Variáveis e funções no Widget (Graph)

No Graph do WBP_HUD, crie variáveis para armazenar estado simples (opcional) e funções para atualizar a UI:

  • ScoreValue (Integer) – opcional
  • ContextMessage (Text) – opcional
  • StaminaNormalized (Float) – opcional (0 a 1)

Crie funções públicas (marque como Public):

  • SetScore(NewScore: Integer)
  • SetContextMessage(NewMessage: Text)
  • SetContextVisible(bVisible: Boolean)
  • SetStaminaNormalized(NewValue: Float)

Implementação típica (em Blueprints):

  • SetScore: TXT_Score -> SetText com ToText (int)
  • SetContextMessage: TXT_Context -> SetText
  • SetContextVisible: TXT_Context ou o container (Border/SizeBox) SetVisibility para Visible ou Hidden
  • SetStaminaNormalized: PB_Stamina -> SetPercent (clamp 0..1)

Binding: quando usar e quando evitar

O que é Binding

Binding é quando você “amarra” uma propriedade do Widget (ex.: texto do score) a uma função que retorna o valor. O problema é que, em muitos casos, essa função pode ser chamada com frequência (inclusive a cada frame), o que pode virar custo desnecessário conforme o HUD cresce.

Recomendação prática

  • Para protótipos: binding pode ser aceitável.
  • Para HUD de gameplay: prefira atualização por eventos (chamar SetScore apenas quando a pontuação muda, por exemplo).

Se ainda assim quiser usar Binding (com cuidado)

Exemplo: bind do texto de score a uma função GetScoreText. Nessa função, você precisaria acessar uma referência confiável (Player/Controller) e ler a variável de score. Isso aumenta dependências e pode causar Accessed None se a referência não estiver pronta. Por isso, o padrão por evento costuma ser mais robusto para iniciantes.

Criando e guardando a referência do Widget (Player Controller ou Character)

O ponto crítico para atualizar o HUD é ter uma referência persistente do widget criado.

Opção A: Criar no Player Controller (recomendado para HUD)

No seu Player Controller (ex.: BP_PlayerController):

  • Crie uma variável HUDRef do tipo WBP_HUD (Object Reference).
  • No Event BeginPlay:
Create Widget (Class: WBP_HUD, Owning Player: Self) -> Promote to variable (HUDRef) -> Add to Viewport

Depois disso, qualquer lógica no Controller (ou chamada recebida) pode fazer:

HUDRef -> SetScore(Score) / SetContextMessage(...) / SetStaminaNormalized(...)

Opção B: Criar no Character

Também funciona, especialmente em projetos simples. O cuidado é que UI costuma ser responsabilidade do Controller (e facilita quando trocar de Pawn). Se criar no Character, mantenha a mesma ideia: variável HUDRef e criação no BeginPlay.

Atualizando pontuação por eventos (sem binding)

1) Fonte da pontuação

Escolha onde a pontuação vive (por exemplo, no Character, Controller ou um componente). Suponha que exista uma variável Score e que ela muda quando o jogador coleta algo.

2) Disparar atualização quando mudar

Quando você incrementar a pontuação:

Score = Score + PointsGained HUDRef -> SetScore(Score)

Se a pontuação for alterada em vários lugares, uma alternativa é criar uma função AddScore(Delta) que sempre atualiza o HUD ao final.

Barra simples (vida/stamina) com ProgressBar

1) Normalização (0 a 1)

ProgressBar usa Percent de 0.0 a 1.0. Se você tem CurrentStamina e MaxStamina:

Normalized = CurrentStamina / MaxStamina HUDRef -> SetStaminaNormalized(Normalized)

Use Clamp (float) para garantir 0..1.

2) Atualização por evento

Atualize a barra apenas quando a stamina/vida mudar (corrida, dano, regeneração). Se você tem regeneração em Tick, ainda dá para reduzir chamadas atualizando em intervalos (Timer) ou apenas quando o valor variar além de um pequeno limiar, mas para um HUD básico, chamar ao mudar já é suficiente.

Mensagem contextual de interação (mostrar/ocultar)

A mensagem contextual deve aparecer apenas quando o jogador estiver “mirando” (ou próximo) de algo interagível e desaparecer quando não estiver.

Implementação simples no Widget

  • SetContextMessage(Text) define o texto.
  • SetContextVisible(true/false) controla visibilidade.

Exemplo de uso:

HUDRef -> SetContextMessage("Pressione E para Interagir") HUDRef -> SetContextVisible(true)

Ao perder o alvo:

HUDRef -> SetContextVisible(false)

Exercício guiado: mensagem contextual ao mirar em um interagível usando Interface + Dispatcher

Objetivo: quando o jogador mirar em um ator interagível, o HUD mostra uma mensagem específica daquele ator; quando sair do alvo, a mensagem some. Vamos usar Interface para o interagível fornecer o texto, e um Event Dispatcher para o sistema de detecção notificar o HUD sem acoplamento direto.

Parte 1 — Interface para fornecer o texto de interação

Crie uma Blueprint Interface (ex.: BPI_Interactable) com uma função:

  • GetInteractionPrompt (Output: Text)

Em cada ator interagível (porta, item, alavanca), implemente a interface e retorne um texto apropriado, por exemplo:

  • Porta: “Pressione E para Abrir”
  • Item: “Pressione E para Coletar”

Parte 2 — Dispatcher no Character (ou componente de interação)

No Character (ou no seu sistema de interação), crie um Event Dispatcher:

  • OnFocusChanged com parâmetros: bHasFocus (Boolean), Prompt (Text)

Ideia: sempre que o alvo em foco mudar, dispare esse dispatcher.

Parte 3 — Detectar o alvo em foco e disparar eventos

Use a lógica de “mirar” que você já tem (ex.: Line Trace a partir da câmera). O importante aqui é: detectar mudança de alvo, não apenas “tem algo”.

Variáveis sugeridas no Character:

  • FocusedActor (Actor Reference)

Fluxo sugerido (em alto nível):

  • Faça Line Trace.
  • Se acertou um ator que implementa BPI_Interactable:
  • Se esse ator é diferente de FocusedActor, atualize FocusedActor e obtenha o texto via Interface (GetInteractionPrompt).
  • Chame OnFocusChanged.Broadcast(true, PromptText).
  • Se não acertou nada interagível e FocusedActor não é nulo:
  • Limpe FocusedActor e chame OnFocusChanged.Broadcast(false, EmptyText).

Observação importante: disparar apenas quando muda evita “spam” de atualização no HUD.

Parte 4 — Conectar o Dispatcher ao HUD

No lugar onde você cria o HUD (idealmente no Player Controller):

  • Depois de criar HUDRef e adicionar ao viewport, obtenha referência do Character (Pawn) e faça o Bind no dispatcher OnFocusChanged.

Exemplo de encadeamento (conceitual):

BeginPlay -> CreateWidget(WBP_HUD) => HUDRef -> AddToViewport -> GetPawn -> Cast to BP_Character -> Bind Event to OnFocusChanged

No evento bindado (ex.: HandleFocusChanged):

  • Se bHasFocus:
  • HUDRef -> SetContextMessage(Prompt)
  • HUDRef -> SetContextVisible(true)
  • Senão:
  • HUDRef -> SetContextVisible(false)

Checklist de depuração (problemas comuns)

  • HUDRef é nulo: confirme que Create Widget foi chamado e que você promoveu para variável antes de usar.
  • Mensagem não aparece: verifique se o container do texto não está com Visibility em Collapsed permanentemente; use Hidden/Visible.
  • Interface não responde: confirme que o ator implementa BPI_Interactable e que o Line Trace está acertando o componente correto.
  • Evento dispara o tempo todo: garanta que você só faz Broadcast quando o alvo muda (comparando com FocusedActor).
  • Texto errado: teste cada interagível retornando um texto diferente no GetInteractionPrompt.

Organização final do HUD (sugestão de nomes e responsabilidades)

ElementoOnde ficaComo atualiza
PontuaçãoVariável no Character/ControllerChamar HUDRef.SetScore quando mudar
Barra (vida/stamina)Variáveis de status no Character/ComponenteChamar HUDRef.SetStaminaNormalized quando mudar
Mensagem contextualInteragível fornece texto via InterfaceDispatcher OnFocusChanged controla SetContextMessage/SetContextVisible

Agora responda o exercício sobre o conteúdo:

Para evitar custo desnecessário de Binding e manter o HUD eficiente, qual abordagem é a mais indicada para atualizar pontuação e barra (vida/stamina)?

Você acertou! Parabéns, agora siga para a próxima página

Você errou! Tente novamente.

A recomendação é atualizar a UI por eventos: criar o widget, guardar HUDRef e chamar funções de atualização somente quando o dado mudar. Isso evita chamadas frequentes de Binding e reduz trabalho por frame.

Próximo capitúlo

Sistema de pontuação e persistência durante a partida (GameMode, GameState e PlayerState)

Arrow Right Icon
Capa do Ebook gratuito Unreal Engine para Iniciantes: Fundamentos de Blueprints e Lógica de Gameplay
59%

Unreal Engine para Iniciantes: Fundamentos de Blueprints e Lógica de Gameplay

Novo curso

17 páginas

Baixe o app para ganhar Certificação grátis e ouvir os cursos em background, mesmo com a tela desligada.