Depuração em Blueprints: breakpoints, logs e diagnóstico de fluxo de execução

Capítulo 16

Tempo estimado de leitura: 10 minutos

+ Exercício

O que é depuração (debug) em Blueprints

Depurar é observar a execução real do seu Blueprint para descobrir por que o comportamento não corresponde ao esperado. Em Blueprints, isso normalmente envolve: pausar a execução em pontos específicos (breakpoints), acompanhar valores mudando em tempo real (watch), imprimir mensagens rápidas na tela (Print String) e registrar informações no Output Log (logs). O objetivo é responder perguntas como: “Este evento está disparando?”, “Quantas vezes ele dispara?”, “Qual valor esta variável tem no momento do erro?”, “Por que este fluxo não passa por aqui?”

Blueprint Debugger: selecionando a instância correta

Um erro comum é depurar o Blueprint “genérico” e esquecer que, em runtime, existem várias instâncias do mesmo Actor. Para depurar corretamente, você precisa apontar o Debugger para a instância que está em jogo.

Passo a passo: escolher o objeto para depuração

  • Inicie o jogo em Play (PIE).
  • Abra o Blueprint que você quer depurar.
  • No topo da janela do Blueprint, use o seletor de Debug Filter para escolher a instância correta (por exemplo, o inimigo específico, o item específico, o Player).
  • Se o comportamento acontece em um Actor que é spawnado, espere ele existir e então selecione-o no Debug Filter.

Quando a instância correta está selecionada, você verá fios (wires) “pulsando” durante a execução e poderá inspecionar valores com mais confiança.

Breakpoints: pausando a execução no ponto exato

Breakpoints interrompem a execução quando um nó específico é alcançado. Isso é ideal para confirmar se um caminho está sendo usado e para inspecionar variáveis no momento do problema.

Como adicionar e usar breakpoints

  • Clique com o botão direito em um nó e escolha Add Breakpoint (ou use o atalho disponível no editor).
  • Rode o jogo. Quando o nó for executado, o jogo pausa e o editor destaca o nó.
  • Com o jogo pausado, passe o mouse sobre variáveis (pins) para ver valores atuais.
  • Use os controles do debugger para continuar (Resume) ou avançar passo a passo quando aplicável.

Dicas práticas

  • Coloque breakpoints em: entrada de eventos, antes de Branches importantes, antes de Set de variáveis críticas, e antes de chamadas que você suspeita estarem duplicadas.
  • Se o breakpoint nunca dispara: o evento não está sendo chamado, o Blueprint não é a instância correta, ou o fluxo está desviando antes do nó.
  • Se o breakpoint dispara “demais”: você provavelmente tem um loop, um evento sendo disparado múltiplas vezes, ou múltiplas instâncias executando a mesma lógica.

Watch Values: acompanhando variáveis em tempo real

“Watch” permite observar valores sem precisar pausar toda hora. É útil para variáveis que mudam rapidamente (pontuação, estado, contadores, flags) e para confirmar se um valor está sendo atualizado no lugar certo.

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

Passo a passo: adicionar watch

  • Durante o Play, com o Blueprint aberto e a instância correta selecionada no Debug Filter, clique com o botão direito em um pin/variável e escolha Watch this value (ou opção equivalente).
  • Observe o valor no painel de depuração enquanto você reproduz o bug.

Use watch para responder: “A pontuação sobe duas vezes por evento?”, “Esta referência vira None em algum momento?”, “Este booleano realmente muda quando eu espero?”

Print String: diagnóstico rápido de fluxo

Print String é a ferramenta mais rápida para confirmar que um trecho de lógica foi executado e com quais valores. É excelente para depuração de fluxo (qual caminho do Branch foi tomado) e para contagem de disparos de eventos.

Boas práticas com Print String

  • Inclua contexto na mensagem: nome do evento, nome do Actor e valores-chave.
  • Padronize prefixos para filtrar mentalmente: [SCORE], [INTERACT], [DAMAGE], [STATE].
  • Use cores diferentes para caminhos diferentes (por exemplo, verde para sucesso, vermelho para erro).
  • Use duração curta (ex.: 1–2s) para não poluir a tela.

Exemplos de mensagens úteis

[SCORE] AddPoints called | Amount=10 | Player=PlayerState_1
[INTERACT] Overlap Begin | Item=BP_Coin_12 | Other=BP_Player
[STATE] CanScore=true | HasScored=false

Mesmo sem “step-by-step”, só o Print String já revela duplicações: se a mesma mensagem aparece duas vezes para uma única ação, você já sabe onde investigar.

Logs no Output Log: registrando com mais controle

Além de imprimir na tela, você pode registrar mensagens no Output Log. Isso é útil quando: você precisa de histórico (mensagens que não somem), quer depurar em sessões longas, ou quer analisar sequência de eventos. Em Blueprints, uma forma comum é usar nós que escrevem no log (dependendo do projeto/plugins) ou encaminhar mensagens para sistemas que registram no Output Log.

Estratégia de “categorias” em Blueprint (quando aplicável)

Mesmo que o nó de log disponível no seu projeto não suporte categorias nativas como em C++, você pode simular categorias com prefixos consistentes e, se existir suporte a categorias, usá-las para filtrar:

  • [BP.Score] para pontuação
  • [BP.Interaction] para interação
  • [BP.AI] para IA
  • [BP.Error] para condições inválidas

O importante é: mensagens devem ser fáceis de buscar e correlacionar com o fluxo.

Diagnóstico de problemas comuns

1) Loops e execução “travando”

Loops em Blueprints podem travar o jogo se não tiverem condição de parada ou se forem acionados em alta frequência. Sinais típicos: queda brusca de FPS, editor congelando, Output Log inundado, ou Print String repetindo sem parar.

  • Coloque um breakpoint dentro do loop para ver se ele está rodando mais do que deveria.
  • Adicione um contador e imprima a cada N iterações (para não inundar): por exemplo, incrementa um LoopCounter e imprime quando LoopCounter % 50 == 0.
  • Verifique se o loop está sendo chamado por um evento de alta frequência (como Tick) sem necessidade.

2) Eventos disparando múltiplas vezes

Isso acontece muito com Overlap, input, timers e lógica duplicada em mais de um lugar. Sintomas: pontuação duplicada, dano duplicado, animação tocando duas vezes, som repetido.

  • Use Print String no início do evento com um identificador do Actor (Get Display Name do Self e do Other Actor) para ver se são instâncias diferentes ou o mesmo evento repetindo.
  • Coloque breakpoint no início do evento e observe a Call Stack/fluxo (quando disponível) e quais condições estão permitindo a execução.
  • Procure por: múltiplos componentes gerando Overlap, colisões em mais de um componente, ou lógica de pontuação tanto no item quanto no jogador.

3) Referências nulas (None) e acesso inválido

Referência nula é quando você tenta usar um objeto que não existe (ainda não foi setado, foi destruído, ou não foi encontrado). Em runtime, isso costuma gerar warnings/erros no log e comportamento quebrado (por exemplo, pontuação não atualiza porque PlayerState é None).

Passo a passo: validar antes de usar

  • Antes de acessar uma referência, use um nó de validação (por exemplo, Is Valid com Branch).
  • No caminho inválido, registre: qual referência falhou e em qual Blueprint.
  • Se a referência deveria existir, coloque breakpoint no momento em que ela é atribuída (Set) para confirmar que está sendo setada e quando.
IsValid(PlayerStateRef)?
  True  -> AddPoints
  False -> Print: [BP.Error] PlayerStateRef is None in BP_Player

Exercício guiado: corrigir bug de pontuação duplicada

Cenário: ao coletar uma moeda (ou item de pontuação), a pontuação aumenta duas vezes em vez de uma. Você vai usar depuração para localizar a causa e corrigir com DoOnce/Gate e validação de estado.

Parte A — Reproduzir e medir o bug

  1. Rode o jogo e colete uma moeda. Confirme que a pontuação sobe em dobro.
  2. No Blueprint responsável pela pontuação (ex.: moeda, jogador, ou sistema de score), adicione Print String no ponto onde a pontuação é incrementada.
  3. Mensagem sugerida: [BP.Score] AddPoints | Amount=1 | Coin=SelfName.
  4. Colete novamente e observe: a mensagem aparece duas vezes para uma única coleta?

Parte B — Encontrar a origem da duplicação

As causas mais comuns para pontuação duplicada em coleta são:

  • Overlap Begin disparando mais de uma vez (por múltiplos componentes colidindo).
  • Lógica duplicada: a moeda chama “AddPoints” e o jogador também chama “AddPoints” para o mesmo evento.
  • Item não é destruído/desativado a tempo e gera novo overlap.

Passo a passo com breakpoints

  1. Coloque um breakpoint no evento de OnComponentBeginOverlap (ou evento equivalente) da moeda.
  2. Coloque outro breakpoint no nó exato onde a pontuação é incrementada.
  3. Rode e colete a moeda. Quando pausar, observe:
    • Quantas vezes o breakpoint do overlap é atingido.
    • Se o Other Actor é sempre o mesmo (Player) ou se há mais de um componente/ator envolvido.
    • Se a execução passa por dois caminhos diferentes que ambos incrementam score.

Parte C — Correção 1: DoOnce para garantir “uma vez por moeda”

Use DoOnce para garantir que a moeda só conceda pontos uma única vez, mesmo que o evento dispare repetidamente.

Implementação sugerida (na moeda)

  1. No início do fluxo do overlap (depois de checar que o Other Actor é o jogador), adicione um DoOnce.
  2. Conecte a saída do DoOnce para a lógica de adicionar pontos.
  3. Após conceder pontos, desative a colisão do item e/ou esconda/destrua o Actor para evitar novos overlaps.
OnBeginOverlap -> (checa se Other é Player) -> DoOnce -> AddPoints -> DisableCollision -> DestroyActor

Observação: se você estiver usando pooling (reutilização de moedas), em vez de destruir, você vai precisar resetar o DoOnce quando a moeda for “reativada”.

Parte D — Correção 2: Gate para controlar janela de pontuação

Gate é útil quando você quer permitir pontuar apenas em uma condição e fechar imediatamente após pontuar, reabrindo depois sob regras claras.

Exemplo de uso

  • Gate começa Open.
  • No primeiro overlap válido, passa, pontua e então Close.
  • Quando o item respawnar/for resetado, você chama Open novamente.
OnBeginOverlap -> Gate(Enter) -> AddPoints -> Gate(Close)

Parte E — Validação de estado: evitando pontuar se já pontuou

Além de DoOnce/Gate, adicione uma variável de estado para tornar o comportamento explícito e fácil de auditar. Exemplo: bCollected (boolean) na moeda.

Passo a passo

  1. Crie bCollected (default: false).
  2. No overlap, faça um Branch: se bCollected for true, não faça nada (e opcionalmente logue).
  3. Quando pontuar, set bCollected = true antes de qualquer ação que possa gerar novo overlap.
OnBeginOverlap
  Branch (bCollected == false)
    True: Set bCollected=true -> AddPoints -> Destroy/Disable
    False: Print [BP.Score] Ignored overlap (already collected)

Parte F — Confirmar a correção com ferramentas de debug

  • Mantenha o Print String e colete a moeda: a mensagem deve aparecer apenas uma vez.
  • Use breakpoint no AddPoints: ele deve pausar uma única vez por coleta.
  • Use watch em bCollected: ele deve mudar para true no primeiro disparo e permanecer true.

Checklist rápido de depuração para Blueprints

SintomaFerramentaO que verificar
Não acontece nadaBreakpoint no evento + Debug FilterInstância correta, evento realmente dispara, fluxo chega no nó
Acontece duas vezesPrint String com contagem + BreakpointsEvento duplicado, múltiplos overlaps, lógica duplicada em dois Blueprints
Valor inesperadoWatch ValuesOnde o valor muda, ordem de execução, resets acidentais
Erro de referência (None)Is Valid + LogsMomento de set da referência, destruição do objeto, timing (BeginPlay vs runtime)
Travamento/loopBreakpoint dentro do loop + contadorCondição de parada, loop acionado por Tick, spam de eventos

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

Ao depurar um Actor que possui várias instâncias durante o Play, qual ação aumenta a chance de você observar o fluxo e os valores da instância que realmente está apresentando o problema?

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

Você errou! Tente novamente.

Em runtime existem várias instâncias do mesmo Actor. Ao escolher a instância correta no Debug Filter, você passa a ver o fluxo (wires pulsando) e inspecionar valores da instância que está em jogo, evitando depurar o objeto errado.

Próximo capitúlo

Empacotamento (Packaging) do projeto e verificação final de gameplay

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

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.