How to Create a Race Car in Unity (2024)

Racing games are a classic, whether found on modern consoles or in old-timey arcades.

Regardless of their rendition though, one of the few fundamentals they have in common is their cars. Cars are one of the key buildings blocks, and will probably be one of the first things you want to learn to make your own racing game.

In this tutorial, we’re going to cover just that: building a race car using the popular Unity Engine. We’ll be covering everything from setting up movement with Unity’s Input System, to adding physics for sterring.

Let’s dive in!

Table of contents

Project Files

You can download a copy of the source code files for the project done in this tutorial here. Note that this tutorial requires good familiarity with Unity and C# scripting.

How to Create a Race Car in Unity (1)

FREE COURSES AT ZENVA

LEARN GAME DEVELOPMENT, PYTHON AND MORE

ACCESS FOR FREE

AVAILABLE FOR A LIMITED TIME ONLY

Setting Up the Input System

After creating a new 3D project in Unity, we need to install the Input System Package first of all.

Installing Input System Package

Let’s open up the Package Manager window (Window > Package Manager):

How to Create a Race Car in Unity (2)

Select Packages > Unity Registry to access all the Unity packages:

How to Create a Race Car in Unity (3)

And install the Input System:

How to Create a Race Car in Unity (4)

Creating Input Actions

Once theInput System Packageis installed, we canright-click on the Project window (inside the Assets folder) and click on Create > Input Actions.

How to Create a Race Car in Unity (5)

We’re going to call this “PlayerControls”anddouble-click to open it up:

How to Create a Race Car in Unity (6)

This is going to open up theInput Actionswindow. On the left panel, we can create anAction Mapby clicking on the+ button. This is basically a category for all your different inputs:

How to Create a Race Car in Unity (7)

We’ll call the first action map “Main“, and create a newActionconnected to the “Main” action map. Actions define what we want to do when pressing certain keys:

How to Create a Race Car in Unity (8)

So first of all, we’re going to create an action called “Move“:

How to Create a Race Car in Unity (9)

Then we want to go over to theProperties panel and set the Action typetoButton:

How to Create a Race Car in Unity (10)

Now we can click on Binding > Path > Listen and then press any button on the keyboard to register and bind it with our Input Action:

How to Create a Race Car in Unity (11) How to Create a Race Car in Unity (12)

Alternatively, if we want our movement to be represented with a Vector2 value between -1 and 1, we can change the Action Type to Value and set the Control Type to Vector2:

How to Create a Race Car in Unity (13)

In that case, we can determine which direction the player needs to move in by adding 2D Vector Composite to the Move action. This will create a new binding with four children bindings called Up, Down, Left, and Right:

How to Create a Race Car in Unity (14)

How to Create a Race Car in Unity (15)

To bind a key to an input action, click on Path > Listen, and hit the corresponding keyboard button (W, A, S, and D):

How to Create a Race Car in Unity (16)

Make sure that all input actions are assigned a key:

How to Create a Race Car in Unity (17)

Additional Inputs

What if we want to plug in a controller for our second player? In that case, we can click on the + (Add) button next to the Actions heading, and then click on Add Binding:

How to Create a Race Car in Unity (18)

If you have Xbox or PlayStation controllers, you can choose the Gamepad option instead of the Keyboard for binding the keys:

How to Create a Race Car in Unity (19)

For specific gamepad controls’ information, refer to the documentation: https://docs.unity3d.com/Packages/[emailprotected]/manual/Gamepad.html

You can also separate the window for each type of controller by adding a new Control Scheme:

How to Create a Race Car in Unity (20)

By clicking on the Control Scheme dropdown at the top-left corner, you can switch over to different control schemes (Keyboard/Controller/Joystick/etc).

If you have multiple control schemes, you need to make sure that each key binding is used in the appropriate control scheme. This can be done by enabling/disabling the checkboxes under ‘Use in Control Scheme‘:

How to Create a Race Car in Unity (21)

Refer to the table below to complete all control schemes:

AccelerateUp Arrow [Keyboard]
AccelerateButton South [Gamepad]
TurnLeft Stick/X [Gamepad]
TurnLeft/Right Arrow (-/+) [Keyboard]

How to Create a Race Car in Unity (22)

Make sure to clickSave Asset before closing the window:

How to Create a Race Car in Unity (23)

Car GameObject

To set up a new GameObject for our car, let’s create a new empty GameObject called “Car”. Then we want to add a Rigidbody component for the physics, a Sphere Collider for the collision, and a Player Input for detecting inputs:

How to Create a Race Car in Unity (24)

We also need to attach a new C# script, which will detect inputs and enable us to drive the car around. Let’s call this script “CarController”:

How to Create a Race Car in Unity (25)

Next, we’re going to right-click on our Car object and click on Create Empty to create a new empty child object. This is going to allow our car model to maintain upright rotation (instead of spinning around with the parent Car object):

How to Create a Race Car in Unity (26)

The car models can be found in the Project Files link above, and you can import them into a Assets > Models > Cars folder. Let’s drag it into our CarModel object:

How to Create a Race Car in Unity (27)

Ensure that the model‘s Y-rotation is correctly facing forward by setting it to 180. Also, adjust the Sphere Collider to match the model’s size. The model should be positioned at the bottom of the sphere:

How to Create a Race Car in Unity (28)

Remember to assign a ‘Player’ tag to the car object too, as follows:

How to Create a Race Car in Unity (29)

Rigidbody Settings

The Rigidbody component controls the car’s position through physics simulation. By default, it is set to be pulled downward by gravity and to react to collisions with other objects.

To simulate a realistic car’s behavior, we’re going to adjust these properties:

  • Drag: 0 → 0.5 (This acts as wind resistance/ground friction in forwarding momentum)
  • Angular Drag: 0.05 → 3 (Same as Drag, but for rotation)
  • Interpolate: None → Interpolate (Smoothes out the effect of running physics at a fixed frame rate)

How to Create a Race Car in Unity (30)

Feel free to tweak the values as you like.

Camera Settings

The Main Camera in the scene will be moving based on the car’s position and rotation, keeping a certain distance away from the car. We’re going to call this ‘Camera Offset‘.

First, we need to create an empty object that will contain our camera as a child object:

How to Create a Race Car in Unity (31)

For the Main Camera to orbit around the car, we need to have the parent container object located at the exact same position as the car. We can copy the position values of the car by Right-click on Transform> Copy Component:

How to Create a Race Car in Unity (32)

Then, we can go to the Main Camera object and right-click on Transform > Paste Component Values:

How to Create a Race Car in Unity (33)

Now you can tweak the position and rotation values of the Main Camera to set the default camera angle:

How to Create a Race Car in Unity (34)

Make sure that you have assigned the Input Action Asset and the Main Camera to the Player Input component:

How to Create a Race Car in Unity (35)

Car Controller Script

Once you have the script attached to our Car GameObject, let’s start editing the script:

How to Create a Race Car in Unity (36)

Creating Variables

To control our car, we need to define some variables. Take a look at the list below for a brief description of each variable:

  • Acceleration (float) – the rate at which the car accelerates forward
  • Turn speed (float) – the rate at which the car rotates left and right when steering
  • Car model (Transform) – the reference to the car’s model, which we want to keep stationary in terms of rotation.
  • Start Model Offset (Vector3) – The distance offset from the car model to its parent object to update the model’s position on every frame.
  • Ground Check Rate (float) – The rate of raycasting in order to determine if the car is on the ground.
  • Last Ground Check Time (float) – The time the previous ground check was performed.
  • Current Y Rotation (float)– The current Y rotation of the car model.
  • Accelerate Input (bool)– Input state for acceleration
  • Turn Input (float) – Input state for turning
  • Rigidbody
using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.InputSystem;public class CarController : MonoBehaviour{ public float acceleration; public float turnSpeed; public Transform carModel; private Vector3 startModelOffset; public float groundCheckRate; private float lastGroundCheckTime; private float curYRot; private bool accelerateInput; private float turnInput; public Rigidbody rig;}

Once all the variables are declared, we can save the script, go back to the editor, and set up the public variables’ values in the Inspector:

How to Create a Race Car in Unity (37)

Detecting Inputs

Since we’re using UnityEngine.InputSystem, we can create some functions that we can connect to the Player Input component attached to the Car object.

The name of the function can be whatever you want, but it should have a parameter of InputAction.CallbackContext.

For example, let’s start working on the function to be called whenthe Accelerate input is detected:

// called when we press down the accelerate inputpublic void OnAccelerateInput (InputAction.CallbackContext context){}

Here, the “context” sends over all the information regarding the input, such as if the button has just been pressed down, the duration of holding down the key, etc.

By checking if its phase is InputActionPhase.Performed, we can ensure that the key is being pressed down:

// called when we press down the accelerate inputpublic void OnAccelerateInput (InputAction.CallbackContext context){ if(context.phase == InputActionPhase.Performed) accelerateInput = true; else accelerateInput = false;}

Similarly, we can read the turn input as a float value (negative = left, positive = right):

// called when we modify the turn inputpublic void OnTurnInput (InputAction.CallbackContext context){ turnInput = context.ReadValue<float>();}

Let’s save the script, and bind the input functions with specific keys. Go to the Player Input component, assign the Car object to the input events (under Events > Main), and select both OnAccelerateInput and OnTurnInput:

How to Create a Race Car in Unity (38)

How to Create a Race Car in Unity (39)

Now, these event functions are connected to the keys which we have mapped in our Input Action Asset.

Defining Offset

Right now, we have the car’s model attached under its parent Car GameObject. In order to fix the model’s position at the current offset from the parent, we’re going to store the initial localPosition in a Vector3 variable, called startModelOffset.

So let’s define the Start() function to set the startModelOffset‘s value:

using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.InputSystem;public class CarController : MonoBehaviour{ ... private Vector3 startModelOffset; void Start () { startModelOffset = carModel.transform.localPosition; }}

We can then define the FixedUpdate function to add force to our car. Remember, FixedUpdate runs 60 times per second consistently (whereas Update runs every single frame), and hence it is useful for physics calculations.

Here, we’re only adding force into the forward direction if we have‘accelerateInput‘ as true:

using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.InputSystem;public class CarController : MonoBehaviour{ ... void FixedUpdate () { if(accelerateInput == true) { rig.AddForce(carModel.forward * acceleration, ForceMode.Acceleration); } }}

Our car model should only rotate around the y-axis based on our turn input. We can directly replace the y-rotation to reflect our turnInput andturnSpeed:

How to Create a Race Car in Unity (40) How to Create a Race Car in Unity (41)

So let’s manually update the rotation inside Update:

public class CarController : MonoBehaviour{ ... void Update () { curYRot += turnInput * turnSpeed * Time.deltaTime; carModel.position = transform.position + startModelOffset; carModel.eulerAngles = new Vector3(0, curYRot, 0); }}

Our final code looks like this:

using System.Collections;using System.Collections.Generic;using UnityEngine;using UnityEngine.InputSystem;public class CarController : MonoBehaviour{ public float acceleration; public float turnSpeed; public Transform carModel; private Vector3 startModelOffset; public float groundCheckRate; private float lastGroundCheckTime; private float curYRot; private bool accelerateInput; private float turnInput; public Rigidbody rig; void Start () { startModelOffset = carModel.transform.localPosition; } void Update () { curYRot += turnInput * turnSpeed * Time.deltaTime; carModel.position = transform.position + startModelOffset; carModel.eulerAngles = new Vector3(0, curYRot, 0); } void FixedUpdate () { if(accelerateInput == true) { rig.AddForce(carModel.forward * acceleration, ForceMode.Acceleration); } } // called when we press down the accelerate input public void OnAccelerateInput (InputAction.CallbackContext context) { if(context.phase == InputActionPhase.Performed) accelerateInput = true; else accelerateInput = false; } // called when we modify the turn input public void OnTurnInput (InputAction.CallbackContext context) { turnInput = context.ReadValue<float>(); }}

And that’s that for this tutorial!

Conclusion

Congratulations on concluding the tutorial!

You now have a car GameObject inside Unity that you can accelerate forward and steer left and right! You’ve also already tackled setting up Rigidbody, Colliders, and Player Input components, aside from using models and scripting in Unity.

As for the next step, well you’re ready to continue developing your project further! You could start by creating the scenery and road environment, or even start considering splitting the screen to add multiplayer, for instance. There is no limit what you can do with these foundations – so don’t be afraid to experiment!

We wish you the best of luck implementing your future games!

Want to learn more about racing games in Unity? Try our complete Build an Arcade Kart Racing Gamecourse.

Did you come across any errors in this tutorial? Please let us know by completing this form and we’ll look into it!

FREE COURSES

How to Create a Race Car in Unity (42)

FINAL DAYS: Unlock coding courses in Unity, Godot, Unreal, Python and more.

How to Create a Race Car in Unity (2024)
Top Articles
Latest Posts
Recommended Articles
Article information

Author: Manual Maggio

Last Updated:

Views: 6468

Rating: 4.9 / 5 (69 voted)

Reviews: 84% of readers found this page helpful

Author information

Name: Manual Maggio

Birthday: 1998-01-20

Address: 359 Kelvin Stream, Lake Eldonview, MT 33517-1242

Phone: +577037762465

Job: Product Hospitality Supervisor

Hobby: Gardening, Web surfing, Video gaming, Amateur radio, Flag Football, Reading, Table tennis

Introduction: My name is Manual Maggio, I am a thankful, tender, adventurous, delightful, fantastic, proud, graceful person who loves writing and wants to share my knowledge and understanding with you.