Introduction to Rigidbody 2D Movement in Unity: A Beginner’s Guide

Welcome to the world of Unity game development! Today, we’re diving into one of the most important skills in 2D game development: making things move. Whether it’s a player-controlled character or an NPC, learning how to control movement is a must. In the second part of this series we will focus on Unity’s Rigidbody2D component to bring our objects to life.

Another way to move objects is by controlling the Transform directly. I talk about that here.

The Rigidbody2D component enables your object to interact with Unity’s physics engine. This includes features like gravity, collisions, and smooth movement. Depending on how you set up the Rigidbody2D, you can achieve different types of movement.

There are two main ways to control movement using a Rigidbody. First, by creating a Dynamic Rigidbody. This allows you respond to physics, gravity and collisions in a realistic looking way. This is great for most use cases. The second way is by using a Kinematic Rigidbody. This is less common, but this gives you full control of the movement while being able to detect collisions. If you have a more arcade like game feel then this may be an option.

Option 1: Using Velocity with a Dynamic Rigidbody

A Dynamic Rigidbody2D responds to physics forces like gravity and collisions. Using the linearVelocity property allows you to directly control the speed and direction of movement while letting Unity handle other physics interactions.

Code Example: Moving Using linearVelocity
using UnityEngine;

public class MoveDynamicRigidbody : MonoBehaviour
{
    // Show this in the editor without it being public 
    [SerializeField] private float moveSpeed = 5f; // Movement speed

    private Rigidbody2D _rigidbody; // Reference to Rigidbody2D
    private Vector2 _movement; // Stores the movement direction

    private void Start()
    {
        // Get the Rigidbody2D component
        _rigidbody = GetComponent<Rigidbody2D>();
    }

    private void Update()
    {
        // Get input from the arrow keys or WASD
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");

        // Set the movement direction, make sure diagonal input is accounted for
        _movement = new Vector2(horizontal, vertical).normalized;
    }

    private void FixedUpdate()
    {
        // Set the Rigidbody2D's velocity
        _rigidbody.linearVelocity = _movement * moveSpeed;
    }
}
What’s Happening Here?
  1. _rigidbody.linearVelocity: Directly sets the speed and direction of the object.
  2. We Normalize the input so moving diagonally isn’t faster than simply moving up, down, left or right. This is important in a top-down game.
  3. FixedUpdate: Ensures smooth physics calculations (called at consistent intervals).
Key Notes for Dynamic Rigidbody:
  • The Rigidbody2D will be affected by forces like gravity and collisions.
  • If you don’t want gravity to affect the object, set Gravity Scale to 0 in the Rigidbody2D settings.

Option 2: Using MovePosition with a Kinematic Rigidbody

A Kinematic Rigidbody2D doesn’t respond to forces like gravity or collisions unless you programmatically control it. The MovePosition method is ideal for precise, physics-aware movement.

Code Example: Moving Using MovePosition
using UnityEngine;

public class MoveKinematicRigidbody : MonoBehaviour
{
    // Show this in the editor without it being public 
    [SerializeField] private float moveSpeed = 5f; // Movement speed

    private Rigidbody2D _rigidbody; // Reference to Rigidbody2D
    private Vector2 _movement; // Stores the movement direction

    private void Start()
    {
        // Get the Rigidbody2D component
        _rigidbody = GetComponent<Rigidbody2D>();
        
        // Set Rigidbody to Kinematic (this can be set in the editor directly)
        _rigidbody.bodyType = RigidbodyType2D.Kinematic; 
    }

    private void Update()
    {
        // Get input from the arrow keys or WASD
        float horizontal = Input.GetAxis("Horizontal");
        float vertical = Input.GetAxis("Vertical");

        // Set the movement direction
        _movement = new Vector2(horizontal, vertical).normalized;
    }

    void FixedUpdate()
    {
        // Calculate the target position
        Vector2 targetPosition = _rigidbody.position + _movement * (moveSpeed * Time.fixedDeltaTime);

        // Move the Rigidbody2D to the target position
        _rigidbody.MovePosition(targetPosition);
    }
}
What’s Happening Here?
  1. _rigidbody.bodyType: Sets the Rigidbody to Kinematic in the script.
  2. _rigidbody.position: Gets the current position of the Rigidbody2D.
  3. Time.fixedDeltaTime: Make sure the movement is happens smoothly each physics step.
  4. MovePosition: Moves the Rigidbody2D to a specified position while accounting for collisions.
Key Notes for Kinematic Rigidbody:
  • A Kinematic Rigidbody ignores forces like gravity.
  • Use MovePosition for smooth and collision-aware movement.

Comparing Dynamic and Kinematic Movement

FeatureDynamic Rigidbody (Velocity)Kinematic Rigidbody (MovePosition)
Physics InteractionResponds to forces and gravityIgnores forces; only moves as scripted
GravityEnabled by defaultDisabled (manually scripted if needed)
Movement ControlDirectly sets speed and directionMoves to a target position
Use CasesRealistic movement with gravity and collisionsPrecise, scripted movement (e.g., for AI)

Where should you perform input and movement

You should note that we have our input coded into the Update function and we implement the movement in FixedUpdate. This is best practice, from reading the Unity documentation you should generally use FixedUpdate to move KinematicBodies

Special Note for versions previous to Unity 6

Unity 6 now uses the new linearVelocity property instead of the older velocity property. You should use this in all places where you would use the velocity property in older versions. Our code example uses linearVelocity which is the modern approach. You will get a warning in Unity 6 and above if you try to stick with using velocity but your code will still run.

Option 3 : Using Forces to control your RigidBody

Another option is to use forces to control movement. In this scenario you let Unity completely control the movement. You just set off a force or reapply a force and watch what happens. This is great for platformers, space simulations and more.

Example: Using Forces to Move a Rigidbody2D

When using a Rigidbody2D, you can apply forces to make objects move. This approach integrates Unity’s physics system, which can create more dynamic and natural movements. Below is a simple example of using forces for movement.


Code Example: Applying Forces to a Rigidbody2D

using UnityEngine;

public class MoveWithForce : MonoBehaviour
{
    // Show this in the editor without it being public 
    [SerializeField] private float forceStrength = 10f; // How strong the applied force is

    private Rigidbody2D _rigidbody; // Reference to the Rigidbody2D component

    private void Start()
    {
        // Get the Rigidbody2D component
        _rigidbody = GetComponent<Rigidbody2D>();
    }

    private void Update()
    {
        // Get input from the arrow keys or WASD
        float horizontal = Input.GetAxis("Horizontal"); // Left (-1) and Right (+1)
        float vertical = Input.GetAxis("Vertical");     // Down (-1) and Up (+1)

        // Create a direction vector
        Vector2 forceDirection = new Vector2(horizontal, vertical);

        // Apply the force
        ApplyForce(forceDirection);
    }

    private void ApplyForce(Vector2 direction)
    {
        // Only apply force if there is input
        if (direction.magnitude > 0)
        {
            _rigidbody.AddForce(direction * forceStrength);
        }
    }  
}

What’s Happening Here?

  1. AddForce: Adds a force to the Rigidbody2D, making it accelerate in the specified direction.
  2. direction * forceStrength: Scales the force by a forceStrength multiplier for adjustable movement speed.
  3. Input-Based Movement: Detects player input from the keyboard using Input.GetAxis.

Key Notes

  • Smooth Start/Stop: Since forces simulate real-world physics, movement may feel a bit “slippery” or take time to stop. You can fine-tune this by adjusting the Rigidbody2D’s drag property in the Inspector.
  • Mass Matters: The force will have less effect on objects with higher mass. Adjust the Rigidbody2D’s mass in the Inspector to tweak the movement.
  • Gravity: By default, gravity affects the Rigidbody2D. To disable it, set the Gravity Scale to 0 in the Rigidbody2D component.

Pros and Cons of Using Forces

ProsCons
Feels dynamic and realisticCan feel less precise for controlled movement
Integrates seamlessly with Unity physicsRequires fine-tuning for smooth movement

Why Use Forces?

This method is ideal for games where you want objects to feel dynamic or interact naturally with other physics-based elements (e.g., a ball in a soccer game or a spaceship flying in space). Experiment with force-based movement to see how it fits your game!

Which One Should You Use?

  • Dynamic Rigidbody + linearVelocity: Perfect for player characters or objects that need realistic physics behavior.
  • Kinematic Rigidbody + MovePosition: Best for controlled, scripted movements like patrolling NPCs or moving platforms.
  • Dynamic Rigidbody + Forces: Perfect for the most realistic physics behavior and reactions.

Try these methods out and see how they fit into your game. Happy coding! 🚀