Root Motion na Unity: Quando Usar e Quando Desligar

Unity root motion ou In Place? Entenda Apply Root Motion, OnAnimatorMove com CharacterController e Rigidbody, e corrija o personagem que volta ao lugar.
Root Motion na Unity: Quando Usar e Quando Desligar
Root motion na Unity é quando a própria animação move o personagem: o deslocamento gravado no clip (o passo de uma caminhada, o avanço de um golpe) é aplicado no GameObject pelo Animator. A alternativa é a animação In Place, em que o corpo anima no lugar e o seu script decide para onde e com que velocidade o personagem anda. Nenhum dos dois é melhor em geral: a escolha depende do tipo de jogo e de quanto controle você quer dar ao jogador.
Aqui você vai entender a diferença na prática, ligar o Apply Root Motion, controlar o movimento com OnAnimatorMove usando CharacterController e Rigidbody, saber quando não usar root motion e corrigir os dois bugs clássicos: o personagem que volta ao ponto inicial e o que escorrega.
O que é Root Motion na Unity
Num clip Humanoid, a Unity calcula duas referências a cada frame:
- Body Transform: o centro de massa do personagem, a referência mais estável do corpo.
- Root Transform: a projeção do Body Transform no plano Y, calculada em tempo de execução.
A cada frame, a variação do Root Transform vira um delta de posição e rotação. Com Apply Root Motion ligado, esse delta é somado ao GameObject. Em rigs Generic, a referência é o osso escolhido em Root Node na aba Rig.
Na prática: um clip de corrida do Mixamo sem "In Place" desloca o corpo para a frente a cada ciclo. Com root motion, o GameObject anda exatamente essa distância. A velocidade do personagem passa a ser a velocidade em que o animador animou a corrida.
Root Motion vs In Place: diferença prática
| Root Motion | In Place + script | |
|---|---|---|
| Quem move | O clip | O seu código |
| Pé deslizando | Praticamente nunca | Acontece se a velocidade não bate com a animação |
| Resposta ao input | Segue a aceleração da animação | Imediata, você controla |
| Golpe com avanço | Distância exata do clip | Você programa o avanço |
| Ajuste de velocidade | Mexer no clip ou no multiplicador | Mudar um número |
| Multiplayer | Mais difícil de prever no servidor | Simples de sincronizar |
Jogos de ação em terceira pessoa com personagem pesado, combate com deslocamento e animações de interação (subir em borda, abrir porta) tiram muito proveito de root motion. Plataforma, shooter rápido, top-down e qualquer jogo em que o controle precisa ser preciso ao pixel ficam melhores com In Place.
Existe um meio termo que muitos jogos usam: locomoção In Place pelo script, e root motion só em ataques, esquivas e animações especiais.
Apply Root Motion no Animator
O ajuste é uma caixa no componente Animator: Apply Root Motion. Antes de ligar, confira as importações dos clips na aba Animation do FBX:
- Root Transform Rotation > Bake Into Pose: ligado, a rotação fica no corpo e o GameObject não gira. Use em clips retos (andar e correr para a frente) para o personagem não ir virando aos poucos.
- Root Transform Position (Y) > Bake Into Pose: ligado, a altura fica no corpo. Use em quase tudo, menos em pulos e quedas em que o objeto precisa subir.
- Root Transform Position (XZ) > Bake Into Pose: ligado, o deslocamento horizontal fica no corpo e não vai para o GameObject. Use em idles, para matar a deriva de pequenos deltas acumulados.
Ou seja: Bake Into Pose é o interruptor por clip e por eixo. Ligar o Apply Root Motion no Animator e fazer o bake de XZ num clip específico significa que só aquele clip não desloca o personagem.
Controlando o movimento com OnAnimatorMove
Se um script no mesmo GameObject do Animator implementar o método OnAnimatorMove, a Unity para de aplicar o root motion sozinha e entrega a responsabilidade para você. O Inspector do Animator mostra o campo Apply Root Motion como "Handled by Script". O método roda todo frame, depois que as máquinas de estado e as animações foram avaliadas, e você lê o deslocamento em animator.deltaPosition e animator.deltaRotation.
Isso é útil para três coisas: aplicar o movimento por um CharacterController ou Rigidbody (para respeitar colisão), multiplicar ou filtrar o deslocamento, e decidir por estado se o root motion vale ou não.
Root Motion com CharacterController e Rigidbody
Aplicar o delta direto no transform atravessa paredes. Passe pelo componente de física.
Com CharacterController, arquivo RootMotionController.cs:
using UnityEngine;
[RequireComponent(typeof(Animator), typeof(CharacterController))]
public class RootMotionController : MonoBehaviour
{
[SerializeField] private float gravity = -20f;
[SerializeField] private float rootMotionMultiplier = 1f;
private Animator animator;
private CharacterController controller;
private float verticalVelocity;
private void Awake()
{
animator = GetComponent<Animator>();
controller = GetComponent<CharacterController>();
}
private void OnAnimatorMove()
{
if (controller.isGrounded && verticalVelocity < 0f)
{
verticalVelocity = -2f;
}
verticalVelocity += gravity * Time.deltaTime;
Vector3 delta = animator.deltaPosition * rootMotionMultiplier;
delta.y = verticalVelocity * Time.deltaTime;
controller.Move(delta);
transform.rotation *= animator.deltaRotation;
}
}
O deslocamento horizontal vem do clip, e a gravidade vem do script. O input não move ninguém aqui: ele só alimenta os parâmetros do Animator (como Speed numa Blend Tree), e a animação escolhida desloca o corpo.
Com Rigidbody, mude o Update Mode do Animator para Fixed, para a animação rodar no mesmo passo da física. Arquivo RootMotionRigidbody.cs:
using UnityEngine;
[RequireComponent(typeof(Animator), typeof(Rigidbody))]
public class RootMotionRigidbody : MonoBehaviour
{
private Animator animator;
private Rigidbody rb;
private void Awake()
{
animator = GetComponent<Animator>();
rb = GetComponent<Rigidbody>();
}
private void OnAnimatorMove()
{
if (Time.deltaTime <= 0f) return;
Vector3 velocity = animator.deltaPosition / Time.deltaTime;
velocity.y = rb.linearVelocity.y; // preserva a gravidade
rb.linearVelocity = velocity;
rb.MoveRotation(rb.rotation * animator.deltaRotation);
}
}
Converter o delta em velocidade, em vez de usar MovePosition, deixa a física resolver colisões e rampas. Repare no linearVelocity: é o nome atual no Unity 6, e o exemplo antigo com rb.velocity que circula por aí gera aviso de API obsoleta. Trave as rotações X e Z em Constraints para o personagem não tombar.
Root motion só em ataques e esquivas
Para o meio termo (locomoção por script, golpes por animação), marque os estados de ataque e esquiva com a Tag RootMotion no Inspector do estado e filtre dentro do OnAnimatorMove:
private static readonly int RootMotionTag = Animator.StringToHash("RootMotion");
private bool CurrentStateUsesRootMotion()
{
AnimatorStateInfo state = animator.GetCurrentAnimatorStateInfo(0);
return state.tagHash == RootMotionTag;
}
No OnAnimatorMove, aplique animator.deltaPosition só quando esse método devolver true. Nos outros estados, o script de locomoção move o controller normalmente. Um único dono do movimento por frame evita os dois sistemas somando deslocamento e o personagem andando o dobro.
Escolher entre root motion e script, integrar com física, câmera e combate, e fazer tudo isso parecer bom no controle é o tipo de decisão que trava projeto solo por semanas. No curso de Unity você constrói um jogo completo tomando essas decisões na ordem certa, com o porquê de cada uma, em vez de colar soluções de tutoriais diferentes que não conversam.
Quando NÃO usar Root Motion
- Plataforma 2D ou 3D com pulo preciso. O jogador precisa saber exatamente onde vai cair. Aceleração de animação atrapalha.
- Shooter rápido e jogos competitivos. Resposta imediata vale mais que pé perfeito.
- Multiplayer com previsão no cliente. Root motion depende do estado do Animator, que é mais difícil de reproduzir igual no servidor e no cliente.
- Personagem com velocidade que muda por gameplay (buff de velocidade, lama, gelo). Com root motion, mudar a velocidade exige multiplicar o delta e, para o pé não deslizar, acelerar a animação junto.
- Pixel art e sprite sheet. Não existe root motion útil em sprite, e o movimento por script é o padrão.
Nesses casos, baixe as animações In Place, deixe Apply Root Motion desligado e controle a Blend Tree pela velocidade real. O guia de game feel explica por que resposta imediata pesa tanto na sensação do controle.
Erros comuns: personagem voltando ao ponto inicial e escorregando
Anda e volta para o lugar. O clip tem deslocamento e Apply Root Motion está desligado: o corpo avança dentro do clip e, quando o ciclo reinicia, volta à origem. Ligue o Apply Root Motion ou troque pela versão In Place. Se o personagem anda certo e só "puxa" de volta no fim de um ataque, o clip de ataque precisa de Bake Into Pose em XZ desligado e o Animator com root motion.
Escorrega parado no idle. Pequenos deltas acumulados. Ligue Root Transform Position (XZ) > Bake Into Pose no idle.
Gira sozinho ao andar reto. Rotação residual do mocap. Root Transform Rotation > Bake Into Pose no clip, com Based Upon em Body Orientation.
Afunda ou flutua. Root Transform Position (Y) com Based Upon errado. Use Feet e ligue o bake. Se o problema é só com CharacterController, confira Center e Height do controller.
Atravessa parede. O root motion está indo direto para o transform. Implemente OnAnimatorMove passando pelo CharacterController ou pelo Rigidbody.
Golpe empurra o personagem para fora da plataforma. O clip de ataque tem avanço grande. Reduza com o multiplicador em OnAnimatorMove durante o ataque ou faça um raycast à frente e zere o delta se não houver chão. O avanço de golpe é parte do peso do ataque no sistema de combate corpo a corpo, então prefira limitar a remover.
Próximo passo
Faça o teste lado a lado: duplique o personagem, deixe um com root motion e o outro In Place com script, e jogue com os dois na mesma cena. Em poucos minutos fica claro qual combina com o seu jogo. Se você ainda está configurando os clips, volte ao guia de Mixamo na Unity para baixar as duas versões e acertar o Avatar.
Perguntas frequentes
O que é Apply Root Motion na Unity?
É a opção do componente Animator que pega o deslocamento e a rotação gravados na animação e aplica no GameObject. Ligada, quem move o personagem é o clip. Desligada, o personagem anima no lugar e o seu script é responsável pelo movimento.
Root motion ou In Place: qual é melhor?
Depende do jogo. Root motion dá pés que não deslizam e golpes com deslocamento preciso, bom para ação em terceira pessoa com peso. In Place com movimento por script dá controle imediato e previsível, bom para plataforma, shooter rápido e multiplayer.
Por que meu personagem anda e volta para o lugar?
O clip tem deslocamento, mas o Apply Root Motion está desligado, então o corpo anda dentro do clip e o GameObject fica parado. No fim do ciclo o corpo volta à origem. Ligue o Apply Root Motion ou baixe a versão In Place da animação.
Dá para usar root motion só em algumas animações?
Dá. Implemente OnAnimatorMove e aplique o deltaPosition só quando o estado atual pede, por exemplo durante ataques e esquivas, deixando a locomoção por script. Também dá para fazer o bake da posição nos clips que não devem mover o personagem.


