Introdução
Abra o seu projeto. Você já deve ter o seu herói (ou quadrado) na tela, certo?
Agora, você precisa que ele ande e pule. Parece simples. Mas se você já tentou seguir tutoriais antigos ou misturou Input com Transform, sabe a dor: o personagem atravessa paredes, o pulo é flutuante ou o bicho desliza no chão como se estivesse no gelo.
A gente sabe como é. Você perde horas caçando a linha de código errada, e a frustração é o primeiro sintoma do M.U.P., o Mais Um Projeto que vai para o HD.
A boa notícia? O segredo para uma movimentação robusta e responsiva não está na genialidade do código, mas na ferramenta certa e no processo correto.
Este post é o seu mapa. Vamos direto ao ponto, usando o Rigidbody2D, a ferramenta da Unity feita para isso.
Passo 1: O Setup Mínimo Viável (O MVP)
Antes de programar, o objeto precisa estar pronto para a física.
Componentes no seu Personagem:
- Sprite Renderer: Para você ver o bicho.
- Collider 2D (Box Collider 2D): Para ele ter um corpo e interagir com o cenário.
- Rigidbody 2D: Este é o componente chave. Ele faz seu objeto ser controlado pela física da Unity (gravidade, massa, colisões).
Atenção Prática: Em Rigidbody 2D, use Collision Detection como Continuous ou Continuous Speculative para evitar que seu personagem “atravesse” plataformas em alta velocidade.
Passo 2: O Script Mestre do Movimento (Horizontal)
Crie um novo script C# (ex: PlayerMovement) e anexe-o ao seu personagem.
A estratégia aqui é clara: usar o Rigidbody para controlar a velocidade do personagem, garantindo que a física da Unity trabalhe a nosso favor.
No topo do seu script, defina as variáveis públicas para fácil ajuste na Inspector:
using UnityEngine;
public class PlayerMovement : MonoBehaviour
{
// Variáveis que você pode ajustar na Inspector. Praticidade!
[Header("Configuração de Movimento")]
public float moveSpeed = 5f;
public float jumpForce = 10f;
// Componente essencial
private Rigidbody2D rb;
// Armazena a direção do input
private float horizontalInput;
void Awake()
{
// Pega o Rigidbody2D assim que o jogo começa
rb = GetComponent<Rigidbody2D>();
}
void Update()
{
// 1. Coleta o Input do jogador a cada frame.
// Input.GetAxisRaw("Horizontal") retorna -1 (Esquerda), 0 (Parado) ou 1 (Direita).
horizontalInput = Input.GetAxisRaw("Horizontal");
}
void FixedUpdate()
{
// 2. Aplica o movimento horizontal no Rigidbody.
// FixedUpdate é o loop correto para manipular a física (Rigidbody).
Move();
}
void Move()
{
// Cria um novo Vetor de Velocidade.
// x: (Direção do Input * Velocidade)
// y: Mantém a velocidade vertical atual (para não anular o pulo/queda).
rb.velocity = new Vector2(horizontalInput * moveSpeed, rb.velocity.y);
// EXTRA: Flipar o sprite
// Se estiver indo para a direita (positivo) e não estiver virado:
if (horizontalInput > 0)
{
transform.localScale = new Vector3(1, 1, 1);
}
// Se estiver indo para a esquerda (negativo) e não estiver virado:
else if (horizontalInput < 0)
{
transform.localScale = new Vector3(-1, 1, 1);
}
}
}
O que você precisa saber:
Update()vs.FixedUpdate(): Coletamos o input emUpdate()(rápido para input) e aplicamos a física emFixedUpdate()(consistente para Rigidbody). Essa é a regra de ouro.rb.velocity: Definir a velocidade do Rigidbody é mais estável do que usartransform.Translate. Evita o jittering (tremedeira) e respeita as colisões de forma correta.
Passo 3: O Pulo que Funciona (Vertical)
O pulo é a parte mais crítica, porque exige uma verificação: o personagem tem que estar no chão para pular!
Vamos adicionar o código de pulo e a verificação do chão:
3.1. Adicionando a Lógica de Pulo em Update()
// ... (Código anterior) ...
[Header("Configuração de Chão")]
public Transform groundCheck; // Objeto vazio na base do pé
public float checkRadius = 0.2f;
public LayerMask groundLayer; // Qual Layer é o chão
private bool isGrounded; // Variável de controle
// ... (Código anterior) ...
void Update()
{
// 1. Coleta o Input do jogador a cada frame.
horizontalInput = Input.GetAxisRaw("Horizontal");
// 2. Verifica se está no chão
// isGrounded = Physics2D.OverlapCircle(posição, raio, qual layer verificar)
isGrounded = Physics2D.OverlapCircle(groundCheck.position, checkRadius, groundLayer);
// 3. Verifica o pulo
if (isGrounded && Input.GetKeyDown(KeyCode.Space))
{
Jump();
}
}
void Jump()
{
// Aplica uma força instantânea para cima.
// O ForceMode.Impulse garante que a força seja aplicada de uma vez.
rb.AddForce(Vector2.up * jumpForce, ForceMode2D.Impulse);
}
// ... (O restante do script Move() continua no FixedUpdate) ...
3.2. A Configuração Visual (No Editor Unity)
- Crie o
groundCheck: Na hierarquia, crie um objeto vazio (Empty) como filho do seu personagem. Chame-o deGroundCheck. - Posicione o
GroundCheck: Arraste este objeto para a base dos pés do seu personagem. Ele será o sensor que verifica se há chão por perto. - Crie a
groundLayer: Vá em Tags & Layers e crie uma nova Layer chamadaGround(ouChao). - Atribua a Layer: Selecione todas as plataformas e terrenos do seu cenário e defina a Layer delas para
Ground. - Ligue tudo no Script: Volte para a Inspector do seu personagem e arraste:
- O objeto
GroundCheckpara o campoGround Checkno script. - Selecione a layer
Groundno campoGround Layerno script.
- O objeto
Conclusão
Pronto. O seu personagem agora tem movimento horizontal suave e um pulo que só acontece quando ele está firmemente no chão.
Criar jogos não é um dom, é um processo. E o primeiro passo é ter o seu core gameplay funcionando de forma sólida. Você não precisa de um código de 1000 linhas, você precisa do código certo.
Pegue este script, aplique no seu projeto e teste agora.
O que fazer agora: Comente abaixo qual foi o bug mais bizarro que você já teve ao tentar fazer um personagem se mover. Eu ouço cada história…
No nosso próximo post, vamos quebrar o problema de como mostrar a vida do seu personagem na tela. A UI é o próximo passo prático para transformar um protótipo em algo que pareça um jogo.




![Código C# na Unity usando [SerializeField] para expor variáveis privadas no Inspector.](https://perai.dev/wp-content/uploads/2025/11/unity-serializefield-vs-public-inspector-tutorial-1.png)
