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:
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
- Adicione um
Canvas Panel(geralmente já vem como raiz). - Score: adicione um
Horizontal Boxancorado no topo esquerdo. Dentro, umImage(ícone opcional) e umTextBlockpara o valor. Marque o TextBlock como Is Variable e renomeie paraTXT_Score. - Mensagem contextual: adicione um
BorderouSizeBoxancorado no centro inferior. Dentro, umTextBlockmarcado como variável, renomeie paraTXT_Context. Comece com texto vazio e configure alinhamento central. - Barra: adicione um
ProgressBarancorado no inferior esquerdo. Marque como variável e renomeie paraPB_Stamina(ouPB_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) – opcionalContextMessage(Text) – opcionalStaminaNormalized(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 -> SetTextcomToText (int)SetContextMessage:TXT_Context -> SetTextSetContextVisible:TXT_Contextou o container (Border/SizeBox)SetVisibilityparaVisibleouHiddenSetStaminaNormalized: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
SetScoreapenas 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
HUDRefdo tipoWBP_HUD(Object Reference). - No
Event BeginPlay:
Create Widget (Class: WBP_HUD, Owning Player: Self) -> Promote to variable (HUDRef) -> Add to ViewportDepois 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:
OnFocusChangedcom 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, atualizeFocusedActore obtenha o texto via Interface (GetInteractionPrompt). - Chame
OnFocusChanged.Broadcast(true, PromptText). - Se não acertou nada interagível e
FocusedActornão é nulo: - Limpe
FocusedActore chameOnFocusChanged.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
HUDRefe adicionar ao viewport, obtenha referência do Character (Pawn) e faça o Bind no dispatcherOnFocusChanged.
Exemplo de encadeamento (conceitual):
BeginPlay -> CreateWidget(WBP_HUD) => HUDRef -> AddToViewport -> GetPawn -> Cast to BP_Character -> Bind Event to OnFocusChangedNo 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 Widgetfoi 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
VisibilityemCollapsedpermanentemente; useHidden/Visible. - Interface não responde: confirme que o ator implementa
BPI_Interactablee que o Line Trace está acertando o componente correto. - Evento dispara o tempo todo: garanta que você só faz
Broadcastquando o alvo muda (comparando comFocusedActor). - Texto errado: teste cada interagível retornando um texto diferente no
GetInteractionPrompt.
Organização final do HUD (sugestão de nomes e responsabilidades)
| Elemento | Onde fica | Como atualiza |
|---|---|---|
| Pontuação | Variável no Character/Controller | Chamar HUDRef.SetScore quando mudar |
| Barra (vida/stamina) | Variáveis de status no Character/Componente | Chamar HUDRef.SetStaminaNormalized quando mudar |
| Mensagem contextual | Interagível fornece texto via Interface | Dispatcher OnFocusChanged controla SetContextMessage/SetContextVisible |