Event Graph: onde a lógica “acontece”
No Blueprint, a maior parte da lógica de gameplay fica no Event Graph. Ele é um grafo orientado por eventos: algo acontece (um evento dispara) e a execução percorre uma cadeia de nós. Diferente de um script que roda “de cima para baixo”, aqui a ordem depende de quem dispara e de como os fios de execução (Exec) estão conectados.
Nós de execução (Exec) e nós de dados
Existem dois tipos de conexões principais:
- Exec (fio branco): controla a ordem de execução. Um nó só “roda” quando recebe Exec.
- Dados: valores (bool, float, vector, referências etc.). Eles fluem para dentro/fora dos nós, mas não determinam por si só quando algo executa.
Uma regra prática: se um nó tem pino Exec, ele é “imperativo” (faz algo em um momento). Se não tem Exec, geralmente é um nó “puro” (pure), que apenas calcula/retorna um valor quando necessário.
Ordem de execução: o que realmente roda primeiro
Em Blueprints, a ordem é definida pelo caminho do Exec. Se você ligar um evento a uma sequência de nós, eles serão executados na ordem do encadeamento. Se você dividir a execução em múltiplos caminhos, a ordem passa a depender do nó que faz a divisão (por exemplo, Sequence) e do evento que disparou.
BeginPlay: inicialização segura
Event BeginPlay dispara quando o jogo começa (ou quando o ator é spawnado durante o jogo). Use para:
- Ouça o áudio com a tela desligada
- Ganhe Certificado após a conclusão
- + de 5000 cursos para você explorar!
Baixar o aplicativo
- Inicializar variáveis e estados (ex.: luz começa apagada).
- Configurar referências (ex.: pegar um componente específico).
- Disparar timers/rotinas controladas.
Evite colocar lógica que depende de input do jogador ou de colisões aqui, a menos que seja para preparar o estado inicial.
Tick: atualização contínua (e quando evitar)
Event Tick roda a cada frame. Ele é útil para coisas que realmente precisam ser atualizadas continuamente (ex.: interpolação manual, checagens de mira, UI dinâmica complexa). Porém, é fácil criar custo desnecessário.
Quando evitar Tick:
- Quando você pode reagir a eventos (overlap, input, timers).
- Quando a lógica só precisa rodar “de vez em quando”.
- Quando você está apenas esperando algo acontecer.
Alternativas comuns: OnComponentBeginOverlap/OnComponentEndOverlap, Set Timer by Event, Timeline e eventos de input.
Eventos de colisão/overlap e eventos de input
Overlap: entrar/sair de uma área
Eventos de overlap são ideais para “gatilhos” de gameplay: quando algo entra ou sai de um volume/área. Em geral, você usa um componente de colisão (ex.: Box Collision) e conecta:
OnComponentBeginOverlap: disparado ao entrar.OnComponentEndOverlap: disparado ao sair.
Esses eventos fornecem informações como Other Actor (quem entrou/saiu) e Other Comp. É comum filtrar para reagir apenas ao jogador.
Input: ações e eixos
Eventos de input disparam quando o jogador pressiona/solta teclas ou move controles. Em Blueprints, você costuma trabalhar com:
- Action (pressionou/soltou): bom para interagir, pular, abrir porta.
- Axis (valor contínuo): bom para movimento, câmera, aceleração.
Uma prática importante: mantenha a lógica de input no Pawn/Character/PlayerController quando possível, e faça os atores do mundo reagirem a chamadas/eventos (para não espalhar input em muitos lugares). Para este capítulo, vamos focar no uso de overlap, que é um padrão muito comum e eficiente.
Nós de controle de fluxo essenciais
Branch (if)
Branch recebe um booleano e escolhe entre dois caminhos: True ou False. Use para validações (ex.: “já está acesa?”).
Exec → Branch(Condition = bIsLightOn) → True: (não faz nada) / False: TurnOnSequence (executar em passos)
Sequence divide um Exec em múltiplas saídas (Then 0, Then 1...). Ele garante a ordem: executa Then 0, depois Then 1, etc. Útil para organizar ações que precisam ocorrer em sequência sem criar um “fio longo”.
DoOnce (executar uma vez)
DoOnce deixa passar a execução apenas na primeira vez. Depois bloqueia até receber Reset. É ótimo para evitar repetição de efeitos (som, partículas, logs) quando um evento pode disparar várias vezes.
Exemplo: tocar um som apenas na primeira entrada na área, e resetar quando sair.
Gate (abrir/fechar passagem)
Gate funciona como uma “porta” para Exec:
Enter: tenta passar.Open: abre a porta.Close: fecha a porta.Toggle: alterna.Start Closed: começa fechada.
Use quando você quer permitir execução apenas em certas condições temporais (ex.: só permitir acender enquanto o jogador estiver dentro).
Delay (espera)
Delay pausa a cadeia de Exec por um tempo e continua depois. Use com cuidado: delays em excesso podem dificultar depuração. Para rotinas repetidas, prefira timers; para animações, prefira timelines.
Timeline (animação/curvas no tempo)
Timeline permite variar valores ao longo do tempo usando curvas (float, vector, color). É excelente para:
- Fade in/out de luz (intensidade).
- Abrir porta suavemente (rotação).
- Interpolar parâmetros de material.
Ela tem pinos como Play, Reverse, Update (a cada passo) e Finished.
Exemplo controlado: mecanismo de luz por área (com proteção contra repetição)
Objetivo: criar um ator que contém uma área de trigger. Quando o jogador entra, a luz acende com transição suave. Quando sai, a luz apaga com transição suave. Além disso, vamos proteger para não repetir efeitos indevidamente (por exemplo, não disparar “acender” se já estiver acesa, e não tocar efeitos repetidamente em overlaps múltiplos).
Estrutura do Blueprint
Crie um Blueprint Actor chamado BP_LightTrigger e adicione componentes:
- Box Collision (ex.:
TriggerBox): define a área. - Point Light (ex.:
PointLight): a luz que será controlada. - (Opcional) Static Mesh: para visualizar um poste/luminária.
Variáveis recomendadas:
bIsPlayerInside(Boolean, default: false)bIsLightOn(Boolean, default: false)TargetIntensity(Float, default: 5000 por exemplo)FadeDuration(Float, default: 0.5)
Passo 1 — Configurar estado inicial no BeginPlay
No Event BeginPlay:
- Defina a intensidade inicial da luz para 0 (apagada).
- Garanta que
bIsLightOnesteja false.
BeginPlay → PointLight.SetIntensity(0) → Set bIsLightOn = falseIsso evita que a luz comece em um estado inesperado.
Passo 2 — Criar a Timeline de fade
Adicione uma Timeline chamada TL_LightFade com:
- Uma trilha Float chamada
Alphaindo de 0 a 1. - Duração =
FadeDuration(você pode ajustar a duração no próprio Timeline ou multiplicar o valor).
No Update da Timeline:
- Use
Lerp (Float)para interpolar intensidade. - Quando acendendo: Lerp de 0 → TargetIntensity.
- Quando apagando: você pode usar
Reversena timeline para voltar de 1 → 0 e manter o mesmo Lerp.
TL(Update) → SetIntensity( Lerp(0, TargetIntensity, Alpha) )Assim, você não precisa de Tick: a Timeline já atualiza apenas durante a transição.
Passo 3 — Overlap Begin: entrar na área e acender
No evento TriggerBox.OnComponentBeginOverlap:
- Filtre para reagir apenas ao jogador (ex.: checar se
Other Actoré do tipo Character do jogador). Uma forma comum éCast Topara seu Character; outra é comparar comGet Player Character. - Defina
bIsPlayerInside = true. - Use
Branchpara não acender se já estiver acesa. - Se estiver apagada, acione a Timeline com
Playe marquebIsLightOn = true.
BeginOverlap → (validar jogador) → Set bIsPlayerInside=true → Branch(bIsLightOn?) → False: TL_LightFade.Play → Set bIsLightOn=trueProteção contra repetição: o Branch impede que múltiplos overlaps (por exemplo, por componentes diferentes do personagem) reexecutem o “acender”.
Passo 4 — Overlap End: sair da área e apagar
No evento TriggerBox.OnComponentEndOverlap:
- Valide que quem saiu é o jogador.
- Defina
bIsPlayerInside = false. - Use
Branchpara não apagar se já estiver apagada. - Se estiver acesa, use
Reversena Timeline e marquebIsLightOn = false.
EndOverlap → (validar jogador) → Set bIsPlayerInside=false → Branch(bIsLightOn?) → True: TL_LightFade.Reverse → Set bIsLightOn=falseIsso garante que a luz só apaga quando realmente estava acesa.
Refinando a proteção: DoOnce e Gate em cenários comuns
Problema comum: múltiplos BeginOverlap seguidos
Dependendo da configuração de colisão, um personagem pode gerar overlaps múltiplos (por exemplo, cápsula + malha). O Branch(bIsLightOn) já evita repetir o estado, mas você pode querer evitar repetir efeitos adicionais (som, partículas, mensagens).
Aplicando DoOnce para efeitos de entrada/saída
Suponha que você quer tocar um som ao acender e outro ao apagar, mas apenas uma vez por entrada/saída.
- Coloque um
DoOnceantes do “som de acender”. - Resete esse
DoOncequando o jogador sair.
BeginOverlap(validado) → DoOnce → PlaySound(Enter) → (resto do acender)EndOverlap(validado) → DoOnce.Reset → PlaySound(Exit) → (resto do apagar)Assim, mesmo que o BeginOverlap dispare duas vezes, o som não repete.
Aplicando Gate para bloquear ações fora da área
Agora imagine uma variação: a luz só pode ser acionada por input (tecla) enquanto o jogador estiver dentro da área. Você pode usar um Gate:
- No BeginOverlap:
Openo Gate. - No EndOverlap:
Closeo Gate. - No evento de input (ex.:
InputAction Interact): conecte noEnterdo Gate e, depois, faça a lógica de alternar a luz.
BeginOverlap(validado) → Gate.OpenEndOverlap(validado) → Gate.CloseInputAction Interact(Pressed) → Gate.Enter → (toggle da luz)Isso evita checagens constantes e mantém o fluxo explícito.
Usando Sequence e Delay de forma controlada (sem virar “bagunça”)
Sequence para organizar ações de entrada
No BeginOverlap, você pode querer: (1) acender a luz, (2) tocar som, (3) disparar uma partícula. Em vez de encadear tudo em um fio longo, use Sequence:
BeginOverlap(validado) → Sequence → Then0: (lógica da luz) → Then1: (som) → Then2: (partícula)Isso mantém o grafo legível e a ordem explícita.
Delay para um “auto-off” (opcional)
Se você quiser que a luz apague após alguns segundos mesmo com o jogador dentro, você pode usar Delay com uma proteção para não conflitar com a saída:
- Ao entrar: acende, depois
Delay(3s), e então apaga somente sebIsPlayerInsidefor false (ou true, dependendo da regra).
BeginOverlap(validado) → (acende) → Delay(3.0) → Branch(bIsPlayerInside?)Esse padrão mostra por que Branch e variáveis de estado são importantes: sem isso, o Delay poderia apagar a luz mesmo com o jogador ainda dentro.
Tabela rápida: qual nó usar em cada situação
| Necessidade | Nó recomendado | Observação |
|---|---|---|
| Decidir entre dois caminhos | Branch | Base para validações e estados |
| Executar passos em ordem | Sequence | Organiza sem “fio infinito” |
| Evitar repetição até reset | DoOnce | Ótimo para efeitos (som/partícula) |
| Permitir execução só em certas condições | Gate | Excelente com overlap + input |
| Esperar um tempo e continuar | Delay | Use com parcimônia; cuidado com estados |
| Interpolar valores no tempo | Timeline | Substitui Tick em muitos casos |