2D Top Down Movement (Car Style Turning)

Click to load and play the demo.

Make sure that you have completed the previous lesson 2D Top Down Player Movement (Asteroids Style Space Shooter) as you will need the completed script for this.

There are only a handful of changes that are required.

With the previous example the car will drift significantly sideways.

When a player is moving turning there is still momentum from the previous forward direction which causes the player object to appear to drift.

On line 8 a variable to manage the amount of drift is added. This is set to 0.5 in this example so that the amount of sideways velocity is reduced by half on each FixedUpdate.

There are three lines to manage the driving that are added.

Line 28 calculates the forward velocity by getting the up vector of the object and multiplying it by the product of the up vector and the velocity of the rigidbody 2D.

Line 31 has a similar process but for the right velocity which is how much the player is drifting.

Line 33 changes the velocity of the player object to the forward velocity (without drift) and then adds the current rightdrift and multiplies it by the drift factor

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerMovement2DCar : MonoBehaviour
    float driftFactor = 0.5f;
    Vector2 movement;
    Rigidbody2D rb;
    public float speed = 5;
    public float turnSpeed = 50;

    // Start is called before the first frame update
    void Start()
        rb = GetComponent<Rigidbody2D>();

    void OnMove(InputValue iv) {
        movement = iv.Get<Vector2>();
        Debug.Log(movement.x + " - " + movement.y);
    void FixedUpdate() {

        // Get Forward Velocity
        Vector2 forwardVelocity = transform.up * Vector2.Dot(rb.velocity, transform.up);

        // Get Right Velocity (drift)
        Vector2 rightDrift = transform.right * Vector2.Dot(rb.velocity, transform.right);

        rb.velocity = forwardVelocity + rightDrift * driftFactor;

        rb.AddForce(transform.up * speed * movement.y * Time.deltaTime, ForceMode2D.Force);
        rb.MoveRotation(rb.rotation + turnSpeed * -movement.x * Time.deltaTime);


Now attach the camera onto you player object to have the camera track the player.

Copy the boundary object (or add new ones, just remember to put colliders on them) to create a track as is shown in the demo at the top of the lesson.