Ao desenvolver interfaces modernas na Unity com o UI Toolkit, uma das primeiras dúvidas que surgem na cabeça de quem vem do Canvas tradicional (ou de quem está começando a codificar a UI na mão) é: como capturar as interações do jogador?
Embora o atalho .clicked seja muito popular para botões simples, a verdadeira força do ecossistema de UI da Unity reside no método RegisterCallback<T>.
Neste artigo, vamos entender como funciona a arquitetura de eventos do UI Toolkit, a diferença entre os métodos de captura e como utilizar expressões Lambda para deixar o seu código C# muito mais limpo e elegante.
O que é o RegisterCallback?
O RegisterCallback<T> é o método oficial do UI Toolkit para registrar “escutadores” (listeners) de eventos em qualquer elemento da sua árvore visual (VisualElement).
Inspirado no padrão de eventos da Web (similar ao addEventListener do JavaScript), o RegisterCallback utiliza Generics (<T>) no C# para especificar exatamente qual tipo de interação você quer monitorar.
C#
meuElemento.RegisterCallback<TipoDoEvento>(funcaoCallback);
.clicked vs RegisterCallback: Qual a diferença?
É muito comum usar botao.clicked += MinhaFuncao; em projetos iniciais. No entanto, existem diferenças fundamentais entre essas duas abordagens:
| Recurso | .clicked | RegisterCallback<T> |
| Onde funciona? | Exclusivamente em componentes Button. | Em qualquer VisualElement (Imagens, Labels, Painéis, etc.). |
| Informações do Evento | Nenhuma. Apenas avisa que o clique ocorreu. | Recebe um objeto com dados completos (posição do mouse, botão clicado, teclas pressionadas). |
| Variedade de Eventos | Apenas o clique simples. | Suporta dezenas de eventos (hover, foco, arrastar, teclado, etc.). |
| Nível de Controle | Alto nível (Atalho abstrato). | Baixo nível (Acesso direto à árvore de propagação do evento). |
Resumo prático: O
.clickedé ótimo para atalhos em botões convencionais. Mas se você precisa detectar o clique em um slot de inventário (Image), criar um efeito ao passar o mouse por cima de um painel ou saber se o clique foi com o botão direito, oRegisterCallbacké obrigatório.
Os Principais Tipos de Eventos (<T>)
Ao utilizar o RegisterCallback<T>, você substitui o <T> pelo tipo de evento que deseja capturar. Veja os mais utilizados no desenvolvimento de jogos:
1. Interações de Clique e Ponteiro
ClickEvent: Disparado quando o elemento é clicado (pressionado e solto).PointerDownEvent/PointerUpEvent: Captura o exato momento em que o botão do mouse/toque é pressionado ou solto (ideal para mecânicas de “segurar” botão).
2. Movimentação e Hover (Mouse)
MouseEnterEvent/MouseLeaveEvent: Detecta quando o ponteiro do mouse entra ou sai da área do elemento (perfeito para tooltips e efeitos visuais).PointerMoveEvent: Acompanha a posição do ponteiro enquanto ele se move sobre o elemento.
3. Teclado e Foco
KeyDownEvent/KeyUpEvent: Escuta teclas pressionadas enquanto o elemento de UI está com o foco.ChangeEvent<T>: Disparado quando o valor de um componente muda (como o texto de umTextFieldou a posição de umSlider).
Desmistificando a Sintaxe: Expressões Lambda (evt => ...)
Ao usar o RegisterCallback, é muito comum nos depararmos com uma sintaxe que assusta programadores iniciantes:
C#
btnSpin.RegisterCallback<ClickEvent>(evt => estadoAtual = Estado.Girando);
Essa estrutura com a flecha (=>) é chamada de Expressão Lambda (ou função anônima). Ela nada mais é do que um atalho do C# para escrever um método de uma única linha direto no parâmetro, sem precisar poluir a sua classe.
Comparando as duas formas de escrever o mesmo código:
Forma Tradicional (Criando um método separado):
C#
private void OnEnable()
{
// Registramos a função
btnSpin.RegisterCallback<ClickEvent>(MudarEstadoParaGirando);
}
// Tivemos que criar um método inteiro fora do OnEnable apenas para uma linha:
private void MudarEstadoParaGirando(ClickEvent evt)
{
estadoAtual = Estado.Girando;
}
Forma Moderna com Lambda (Em apenas 1 linha):
C#
private void OnEnable()
{
// O 'evt' é o parâmetro com os dados do evento que a Unity passa automaticamente
btnSpin.RegisterCallback<ClickEvent>(evt => estadoAtual = Estado.Girando);
}
Exemplo Prático: Capturando Dados do Clique
Uma das maiores vantagens do RegisterCallback<ClickEvent> é acessar as propriedades do parâmetro evt.
Veja este exemplo onde identificamos se o jogador clicou com o botão esquerdo ou direito do mouse sobre um slot de inventário:
C#
using UnityEngine;
using UnityEngine.UIElements;
public class SlotsInventario : MonoBehaviour
{
private void OnEnable()
{
var root = GetComponent<UIDocument>().rootVisualElement;
VisualElement slotEspada = root.Q<VisualElement>("slot-espada");
// Registra o callback para capturar o clique e inspecionar o botão do mouse
slotEspada.RegisterCallback<ClickEvent>(evt =>
{
// evt.pressedButtons nos diz qual botão acionou o evento
if (evt.button == 0) // 0 = Botão Esquerdo
{
Debug.Log("Equipou o item!");
}
else if (evt.button == 1) // 1 = Botão Direito
{
Debug.Log("Abriu menu contextual do item (Usar / Descartar)!");
}
});
}
}
Boas Práticas: Não se esqueça de Remover o Callback!
Sempre que você registrar um callback em elementos dinâmicos ou ao desativar scripts, é uma boa prática remover o evento para evitar vazamentos de memória (memory leaks), especialmente se estiver apontando para métodos da classe:
C#
private void OnDisable()
{
// Boa prática: desregistrar o callback ao desativar o objeto
meuElemento.UnregisterCallback<ClickEvent>(MinhaFuncao);
}
Conclusão
Entender e dominar o RegisterCallback<T> é o divisor de águas para quem quer programar interfaces de nível profissional na Unity. Ele tira a dependência de componentes engessados de botão e te dá liberdade total para transformar qualquer elemento visual em um componente interativo rico e reativo.
Gostou desta explicação? Deixe seu comentário se tiver alguma dúvida e compartilhe este artigo com outros desenvolvedores da Unity!


