Summary
Rigidbody2D is the Unity component that makes a 2D GameObject participate in the physics simulation. It enables realistic movement driven by forces and velocities, and is required for OnCollisionEnter2D and OnTriggerEnter2D callbacks to fire on a moving object. There are three body types, each suited to a different role. Physics-related code belongs in FixedUpdate, which runs on a fixed timestep independent of frame rate.
Key ideas
Body types:
| Body type | Behaviour | Typical use |
|---|---|---|
Dynamic | Fully simulated — responds to forces, gravity, and collisions | Moving enemies, projectiles, falling objects |
Kinematic | Moves via script only — not affected by forces or gravity; still detects collisions | Player characters, moving platforms |
Static | Does not move | Walls, floors, static hazards |
Gravity Scale: How strongly gravity pulls the object. Set to 0 for top-down 2D games or for kinematic players that manage their own movement.
Freeze Rotation Z: Prevents the physics engine from rotating the object when it collides. Almost always enabled on player characters — a player that tips over when touching a wall is rarely intentional.
FixedUpdate(): The correct place for all physics and Rigidbody2D calls. It runs on Unity’s fixed timestep (default 50 times per second), independent of frame rate. Calling physics in Update causes frame-rate-dependent behaviour — the physics will feel different on machines with different performance.
rb.linearVelocity (Unity 6) / rb.velocity (older Unity): Direct velocity assignment gives crisp, predictable movement. Setting velocity directly is preferred for character movement over AddForce, which introduces acceleration drift.
AddForce(direction * magnitude, ForceMode2D.Impulse): Applies the entire force in a single physics step. Use for one-shot impulses: knockback, jump, explosion.
Vector2.normalized: Returns a direction vector with a magnitude of exactly 1. Normalising before multiplying by speed prevents diagonal movement from being faster than horizontal or vertical movement (diagonal magnitude is √2 ≈ 1.41 without normalisation).
Vector2.ClampMagnitude(velocity, maxSpeed): Limits the magnitude of a vector without changing its direction. Use as a speed cap to prevent velocity accumulating beyond a safe maximum.
In practice
Caching Rigidbody2D in Start:
private Rigidbody2D rb;
private void Awake()
{
rb = GetComponent<Rigidbody2D>();
if (rb == null) Debug.LogError("[PlayerPhysics] No Rigidbody2D found!");
}Physics movement in FixedUpdate:
private void FixedUpdate()
{
HandleMovement();
EnforceSpeedCap();
}
private void HandleMovement()
{
float h = Input.GetAxisRaw("Horizontal");
float v = Input.GetAxisRaw("Vertical");
// Normalise: prevents diagonal speed boost
Vector2 moveDir = new Vector2(h, v).normalized;
// Direct velocity assignment — crisp, predictable
rb.linearVelocity = moveDir * moveSpeed;
}
private void EnforceSpeedCap()
{
// Preserves direction while clamping magnitude
rb.linearVelocity = Vector2.ClampMagnitude(rb.linearVelocity, maxSpeed);
}Knockback impulse:
public void ApplyKnockback(Vector2 sourcePosition)
{
// Direction: away from the damage source
Vector2 direction = ((Vector2)transform.position - sourcePosition).normalized;
rb.linearVelocity = Vector2.zero; // clear existing velocity for clean impulse
rb.AddForce(direction * knockbackForce, ForceMode2D.Impulse);
}Invoke for timed callbacks (e.g. ending a knockback window):
isKnockedBack = true;
Invoke("EndKnockback", knockbackDuration); // calls EndKnockback() after N seconds
private void EndKnockback()
{
isKnockedBack = false;
}Inspector setup checklist
For a typical 2D player character:
- Body Type: Kinematic (if script-driven) or Dynamic (if physics-driven)
- Gravity Scale:
0for top-down; keep default for platformer - Freeze Rotation → Z: enabled (prevents tipping on collision)
- Attach the Rigidbody2D to the same GameObject as the movement script
Gotchas
- Never use
transform.Translateor settransform.positiondirectly on a Dynamic Rigidbody2D — this bypasses the physics engine and causes jitter, missed collisions, and tunnelling. Userb.linearVelocity,AddForce, or (for Kinematic)rb.MovePosition. - Read
InputinUpdate; apply it inFixedUpdate. CallingInput.GetAxisRawinFixedUpdatecan miss input events that occurred between physics steps. rb.linearVelocityis the Unity 6 API name. In older Unity versions (pre-6), the property isrb.velocity. Both refer to the same thing.
Related
- unity-collider2d-and-triggers — collision and trigger detection
- monobehaviour-lifecycle —
FixedUpdateandAwakein the lifecycle - unity-transform — transform-based movement (use instead of Rigidbody2D on non-physics objects)
- unity-getcomponent — caching the Rigidbody2D reference