Funções, Macros e reutilização de lógica em Blueprints na Unreal Engine

Capítulo 6

Tempo estimado de leitura: 9 minutos

+ Exercício

Quando usar Function, Macro e Custom Event

Em Blueprints, existem três formas comuns de encapsular e reutilizar lógica: Functions, Macros e Custom Events. Elas parecem similares no dia a dia, mas têm diferenças importantes em entradas/saídas, fluxo de execução e boas práticas de manutenção.

RecursoTem pinos de Exec?Entradas/SaídasLatente (Delay, Timeline)?ReutilizaçãoUso típico
FunctionDepende: impure tem Exec; pure nãoSim (inputs e outputs)Não (em geral)Alta (inclusive em bibliotecas)Cálculos, validações, getters, pequenas rotinas determinísticas
MacroSim (sempre, como um “bloco” de grafo)Sim (inputs e outputs)Sim (pode conter nós latentes)Média (dentro do Blueprint ou Macro Library)Padronizar padrões de fluxo, “atalhos” de grafo, sequências repetidas
Custom EventSimInputs sim; outputs não (não retorna valor)SimBoa para disparo/assinaturaEntradas de fluxo, chamadas assíncronas, eventos de gameplay, replicação

Regra prática rápida

  • Se você precisa retornar um valor (ex.: pontuação calculada), use Function (preferencialmente Pure se não houver efeitos colaterais).
  • Se você precisa de Delay/Timeline ou quer um “bloco” com Exec que será colado em vários lugares, use Macro.
  • Se você quer disparar algo (sem retorno) e possivelmente lidar com replicação ou encadear lógica assíncrona, use Custom Event.

Functions: Pure vs Impure (e por que isso importa)

Pure Function

Uma Pure Function não tem pinos de execução (Exec) e deve ser determinística: dado o mesmo input, retorna o mesmo output, sem alterar estado do jogo. Ela pode ser chamada “a qualquer momento” pelo Blueprint, inclusive várias vezes por frame, porque o grafo pode reavaliá-la conforme necessário.

  • Ideal para: cálculos, conversões, leitura de variáveis, validações simples.
  • Evite: tocar som, spawnar efeitos, mudar variáveis, destruir/desativar atores.

Impure Function

Uma Impure Function tem Exec (entrada e saída) e pode causar efeitos colaterais: alterar variáveis, chamar funções que mudam estado, interagir com componentes, etc.

  • Ideal para: rotinas de gameplay que mudam estado (ex.: adicionar pontuação, desativar item).
  • Boa prática: mantenha funções impuras pequenas e com nome que indique ação (verbo), por exemplo: AdicionarPontuacao, DesativarItem.

Boas práticas de assinatura (inputs/outputs)

  • Inputs claros: nomeie inputs com intenção, ex.: PontosParaAdicionar em vez de Value.
  • Outputs mínimos: retorne apenas o necessário. Se você precisa de muitos outputs, considere retornar uma struct (se fizer sentido) ou dividir a função.
  • Evite dependências ocultas: se a função depende de algo externo (ex.: referência do Player), prefira receber como input ou documentar claramente.

Macros: reutilização de padrões de fluxo

Macros são como “trechos de grafo” reutilizáveis. Elas são úteis para reduzir repetição visual, principalmente quando você repete o mesmo padrão de Exec com validações e ramificações.

Quando uma Macro é melhor que Function

  • Quando você precisa de nós latentes (por exemplo, Delay), e a lógica precisa ficar encapsulada.
  • Quando você quer um padrão de fluxo com múltiplas saídas de Exec (ex.: Sucesso/Falha), deixando o grafo mais legível.

Cuidados com Macros

  • Debug: macros podem dificultar um pouco o rastreio, porque “expandem” lógica no local de uso.
  • Excesso: não transforme tudo em macro. Para lógica de negócio (regras), functions tendem a ser mais fáceis de manter e testar.

Custom Events: disparo de lógica e organização do fluxo

Custom Events são pontos nomeados de entrada no grafo de execução. Eles não retornam valores, mas aceitam parâmetros. São ótimos para organizar o Event Graph, separar responsabilidades e criar “gatilhos” claros.

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

Quando preferir Custom Event

  • Quando você quer iniciar uma sequência de ações (ex.: “OnColetado”).
  • Quando a lógica pode envolver Delay e você quer manter isso fora de uma function.
  • Quando você precisa de um ponto claro para replicação (em projetos multiplayer), já que eventos podem ser configurados para rodar no servidor/cliente (dependendo do caso).

Passo a passo: criando Functions reutilizáveis no Blueprint do ItemColetável

O objetivo é pegar uma lógica típica de coleta (tocar efeito, adicionar pontuação, desativar item) e refatorar em funções pequenas e reutilizáveis. Isso melhora legibilidade, facilita manutenção e permite reaproveitar em outros itens.

1) Identificar a lógica atual

No Blueprint BP_ItemColetavel, normalmente existe um fluxo no Event Graph parecido com:

  • Evento de overlap/uso
  • Tocar som/efeito
  • Adicionar pontos ao jogador/sistema
  • Desativar o item (ocultar, desabilitar colisão, destruir)

Mesmo que sua implementação exata seja diferente, a refatoração segue a mesma ideia: separar cada responsabilidade em uma função.

2) Criar a Function TocarEfeito

Tipo: Impure Function (vai causar efeito no mundo).

Passos:

  • No BP_ItemColetavel, crie uma nova Function chamada TocarEfeito.
  • Defina inputs opcionais (se fizer sentido): Som (SoundBase), Particula (NiagaraSystem/ParticleSystem), Local (Vector) ou use a localização do próprio ator.
  • Dentro da função, chame os nós de spawn/tocar (por exemplo, tocar som no local e spawnar efeito).

Boa prática: se o item pode não ter som/efeito configurado, faça validação com IsValid antes de spawnar.

// Pseudofluxo (Blueprint mental model):
TocarEfeito():
  if Som é válido: PlaySoundAtLocation(Som, GetActorLocation)
  if Particula é válida: SpawnSystemAtLocation(Particula, GetActorTransform)

3) Criar a Function AdicionarPontuacao

Tipo: Impure Function (vai alterar estado de pontuação em algum lugar).

Decisão importante: onde a pontuação vive? Em muitos projetos, fica no Player, PlayerState, GameState ou um componente de pontuação. A função deve ser escrita para minimizar acoplamento.

Passos (genérico e reutilizável):

  • Crie uma Function chamada AdicionarPontuacao.
  • Inputs sugeridos: QuemColetou (Actor ou seu tipo de personagem), Pontos (Integer/Float).
  • Dentro, obtenha a referência do sistema de pontuação (por exemplo, via cast para o personagem, ou buscando um componente específico no QuemColetou).
  • Aplique o incremento.

Boa prática: se precisar de cast, trate falha de cast com um ramo claro e comentário; não deixe o grafo “mudo” quando falhar.

// Pseudofluxo:
AdicionarPontuacao(QuemColetou, Pontos):
  if QuemColetou tem componente Score:
     Score.Add(Pontos)
  else:
     (opcional) Print/Log em desenvolvimento

4) Criar a Function DesativarItem

Tipo: Impure Function.

Objetivo: encapsular o que significa “sumir” para o seu item. Você pode destruir o ator ou apenas desativá-lo para reuso/pooling.

Passos:

  • Crie a Function DesativarItem.
  • Dentro, aplique um conjunto consistente de ações, por exemplo:
  • Desabilitar colisão do componente principal (ou do ator).
  • Ocultar no jogo (SetActorHiddenInGame).
  • Desabilitar tick (se aplicável).
  • Opcional: DestroyActor (se você não pretende reutilizar).

Boa prática: escolha um padrão e use sempre. Se alguns itens destroem e outros escondem, documente isso no Blueprint com comentários.

5) Reorganizar o Event Graph para usar as funções

Agora o evento de coleta fica curto e legível, chamando as funções em sequência.

// Pseudofluxo do evento de coleta:
OnColetado(QuemColetou):
  TocarEfeito()
  AdicionarPontuacao(QuemColetou, PontosDoItem)
  DesativarItem()

Resultado esperado: o Event Graph vira um “roteiro” de alto nível, e os detalhes ficam dentro das funções.

Quando transformar parte disso em Macro

Se você perceber que vários Blueprints repetem o mesmo padrão de validação e execução, por exemplo:

  • Validar QuemColetou não nulo
  • Checar se já foi coletado
  • Executar sequência

Você pode criar uma Macro como ExecutarSeNaoColetado com duas saídas de Exec: Executar e Ignorar. Isso reduz “nós de branch” repetidos em vários lugares.

// Ideia de Macro:
ExecutarSeNaoColetado(bJaColetado):
  Branch(!bJaColetado)
    True -> Exec: Executar
    False -> Exec: Ignorar

Boa prática: use macro para padronizar fluxo; use function para regras e ações.

Bibliotecas simples de funções (Blueprint Function Library)

Quando uma função não depende do estado de um ator específico e pode ser útil em vários Blueprints, faz sentido colocá-la em uma Blueprint Function Library. Ela é um conjunto de funções estáticas acessíveis de qualquer Blueprint.

O que é um bom candidato para Function Library

  • Conversões e formatações (ex.: converter enum para texto).
  • Cálculos genéricos (ex.: calcular pontuação bônus com base em multiplicador).
  • Funções utilitárias que recebem tudo por parâmetro e não dependem de variáveis internas do ator.

Passo a passo: criar uma biblioteca de funções

  • No Content Browser: Add > Blueprints > Blueprint Function Library.
  • Nomeie, por exemplo: BFL_GameplayUtils.
  • Crie uma função, por exemplo: CalcularPontuacaoFinal.
  • Marque como Pure se for apenas cálculo.
// Exemplo de assinatura:
CalcularPontuacaoFinal(PontosBase:int, Multiplicador:float) -> PontosFinais:int

Como usar: em qualquer Blueprint, procure pelo nome da função da biblioteca e conecte como um nó comum.

Observação importante: ações que dependem de mundo (spawn de efeito, tocar som) geralmente não são bons candidatos para Function Library, a menos que você passe explicitamente contexto suficiente (World Context) e mantenha a função bem genérica. Para iniciantes, prefira manter TocarEfeito dentro do próprio ator do item.

Legibilidade: comentários, organização e padrões de nome

Organizando grafos com comentários

  • Use Comment Boxes para agrupar blocos: “Validação”, “Efeitos”, “Pontuação”, “Desativação”.
  • Escreva comentários que expliquem por que algo existe, não apenas o que o nó faz.
  • Mantenha o fluxo principal na horizontal (esquerda para direita) e evite cruzar fios.

Reroute nodes e alinhamento

  • Use Reroute Nodes para reduzir fios longos e cruzamentos.
  • Alinhe nós e mantenha espaçamento consistente; isso reduz erros ao editar depois.

Padrões de nome

  • Functions impuras: verbo no infinitivo, ex.: DesativarItem, AplicarDano.
  • Functions puras: nome descritivo de retorno, ex.: ObterValorDeVenda, EstaColetado.
  • Booleans: prefixo b (ex.: bJaColetado) e nomes afirmativos.

Atividade prática: refatorar o ItemColetável

Objetivo

Transformar um Event Graph “grande” em um fluxo curto chamando três funções reutilizáveis: TocarEfeito, AdicionarPontuacao, DesativarItem.

Checklist de execução

  • Crie as 3 functions no BP_ItemColetavel.
  • Garanta que TocarEfeito valide assets opcionais (som/efeito) antes de usar.
  • Faça AdicionarPontuacao receber QuemColetou e Pontos por input.
  • Padronize DesativarItem (ocultar + desabilitar colisão, ou destruir).
  • No evento de coleta, substitua nós diretos por chamadas às funções.
  • Adicione Comment Boxes no Event Graph e dentro das funções quando houver decisões (ex.: por que destruir vs ocultar).

Desafio extra (opcional)

  • Crie uma Pure Function no item chamada ObterPontosDoItem que retorna o valor final (base + bônus). Use-a antes de chamar AdicionarPontuacao.
  • Crie uma Macro local ExecutarSeValido para validar QuemColetou e evitar repetição de branches se você tiver mais de um ponto de coleta.

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

Você precisa reutilizar um trecho de lógica que inclui Delay e quer encapsular um padrão de fluxo com saídas de Exec (por exemplo, Sucesso/Falha) para colar em vários pontos do grafo. Qual recurso é mais adequado?

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

Você errou! Tente novamente.

Macros são indicadas para reutilizar padrões de fluxo com pinos de Exec e podem conter nós latentes como Delay. Functions (especialmente Pure) não são ideais para isso, e Custom Events não retornam valores.

Próximo capitúlo

Referências, casting e comunicação entre Blueprints (sem acoplamento excessivo)

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

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.