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?
_rigidbody.linearVelocity
: Directly sets the speed and direction of the object.- 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.
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?
_rigid
body.bodyType
: Sets the Rigidbody to Kinematic in the script.
: Gets the current position of the Rigidbody2D._rigid
body
.positionTime.fixedDeltaTime
: Make sure the movement is happens smoothly each physics step.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
Feature | Dynamic Rigidbody (Velocity) | Kinematic Rigidbody (MovePosition) |
---|---|---|
Physics Interaction | Responds to forces and gravity | Ignores forces; only moves as scripted |
Gravity | Enabled by default | Disabled (manually scripted if needed) |
Movement Control | Directly sets speed and direction | Moves to a target position |
Use Cases | Realistic movement with gravity and collisions | Precise, 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?
AddForce
: Adds a force to the Rigidbody2D, making it accelerate in the specified direction.direction * forceStrength
: Scales the force by aforceStrength
multiplier for adjustable movement speed.- 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
Pros | Cons |
---|---|
Feels dynamic and realistic | Can feel less precise for controlled movement |
Integrates seamlessly with Unity physics | Requires 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! 🚀