---
title: "Lesson 1.4 - Step into the Driver's Seat"
content_type: tutorial
url: "https://learn.unity.com/tutorial/lesson-1-4-use-user-input-to-control-the-vehicle?language=en"
language: en
difficulty: beginner
duration_minutes: 50
unity_version:
  - "6.0"
  - "6.3"
supported_unity_versions:
  - name: "6.0"
    url: "https://learn.unity.com/tutorial/lesson-1-4-use-user-input-to-control-the-vehicle.md?language=en&version=6.0"
  - name: "6.3"
    url: "https://learn.unity.com/tutorial/lesson-1-4-use-user-input-to-control-the-vehicle.md?language=en&version=6.3"
  - name: "2022.3"
    url: "https://learn.unity.com/tutorial/lesson-1-4-use-user-input-to-control-the-vehicle.md?language=en&version=2022.3"
  - name: "2021.3"
    url: "https://learn.unity.com/tutorial/lesson-1-4-use-user-input-to-control-the-vehicle.md?language=en&version=2021.3"
available_languages:
  - name: "en"
    url: "https://learn.unity.com/tutorial/lesson-1-4-use-user-input-to-control-the-vehicle.md?language=en"
  - name: "es"
    url: "https://learn.unity.com/tutorial/leccion-1-4-al-volante.md?language=es"
  - name: "ja"
    url: "https://learn.unity.com/tutorial/lesson-1-4-use-user-input-to-control-the-vehicle-jp.md?language=ja"
  - name: "ko"
    url: "https://learn.unity.com/tutorial/1-4gang-juhaeng-junbi.md?language=ko"
last_updated: "2026-08-04T14:24:09.000Z"
---

# Lesson 1.4 - Step into the Driver's Seat

Use methods, vectors, and variables to read arrow key input and drive a vehicle that moves forward, backward, and turns.

**Overview:**

In this lesson, we need to hit the road and gain control of the vehicle. In order to do so, we need to detect when the player is pressing the arrow keys, then accelerate and turn the vehicle based on that input. Using new methods, Vectors, and variables, you will allow the vehicle to move forwards or backwards and turn left to right.

**Project Outcome:**

When the player presses the up/down arrows, the vehicle will move forward and backward. When the player presses the left/right arrows, the vehicle will turn.

Overview: [Video](https://connect-mediagw.unity.com/h1/20241204/videos/22878f8b-65a0-4529-abc3-acd05d286a56_CWC_U1.L4.S0_Intro_U6.mp4) ([Transcript (en)](https://connect-mediagw.unity.com/h1/20241204/a7de0550-7199-44de-a09f-ff8a39342c1e_CWC_U1.L4.S0_Intro_U6.mp4.vtt))

## 1. Configure project settings for the Input System

The code you’ll add in the following steps uses the **Input System** to handle player controls. To ensure the code works correctly, verify that your project is configured to allow both input systems to run side by side.

Follow the video and instructions below:

[Video](https://connect-mediagw.unity.com/h1/20250903/videos/89a8fcf6-41e6-4a5c-aae5-49a3825881cf_ChangeInputSystem.mp4)

## Instructions

**1.** Open the **Player Settings**:

- From the main menu, select **Edit** > **Project Settings,** then select the **Player** category from the leftmost panel.

**2.** Enable support for both input systems:

- Find the **Configuration** section.
- From the **Active Input Handling** dropdown, select **Both**.
- Select the **Apply** button to confirm the change.

The Unity Editor will automatically restart to apply this setting. After restarting, your project will be correctly configured to handle input from both the original Input Manager and the newer Input System.

## 2. Allow the vehicle to move left/right

Until now, the vehicle has only been able to move straight forward along the road. We need it to be able to move left and right to avoid the obstacles.

[Video](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%22f5Dcpkp7DZC0QRMvpxgZoC%22%5D.body%5B_key==%22f5Dcpkp7DZC0QRMvpxgZuI%22%5D.overviewVideo/Unit%201.4%20-%20Step%202%20-%20Allow%20the%20vehicle%20to%20move%20left:right_20260619_141807.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%22f5Dcpkp7DZC0QRMvpxgZoC%22%5D.body%5B_key==%22f5Dcpkp7DZC0QRMvpxgZuI%22%5D.subtitles/CWC_U1.L4.S1_U6.mp4_20260505_033307.srt))

1. At the top of PlayerController.cs, add a **_public float turnSpeed;_** variable
2. In **_Update()_**, add  **_transform.Translate(Vector3.right \* Time.deltaTime \* turnSpeed);_**
3. Run your game and use the **_turnSpeed_** **variable slider** to move the vehicle left and right

![](https://connect-mediagw.unity.com/h1/20190522/learn/images/647af73c-5584-4829-ac92-cf047b3d2dd7_1_4_1.png)

## 3. Add a MoveAction variable

Now let’s introduce Unity’s newer Input System and expose a Move Action so you can bind the arrow keys directly in the Inspector.

[Video](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%22f5Dcpkp7DZC0QRMvpxgcJf%22%5D.body%5B_key==%22f5Dcpkp7DZC0QRMvpxgcPl%22%5D.overviewVideo/Unit%201.4%20-%20Step%203%20-%20Add%20a%20MoveAction%20variable_20260619_033726.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%22f5Dcpkp7DZC0QRMvpxgcJf%22%5D.body%5B_key==%22f5Dcpkp7DZC0QRMvpxgcPl%22%5D.subtitles/Unit%201.4%20-%20Step%203%20-%20Add%20a%20MoveAction%20variable_20260619_033726_20260622_232518.vtt))

1. In **PlayerController.cs**, add a public **InputAction** field so it shows up in the **Inspector** window.
2. Save, return to Unity, then in the **Inspector** window expand the **Move Action** section.
3. If you get an error about **InputAction** not being found, hover over the error and use **Quick** **Fix** to add “using UnityEngine.InputSystem;”,or manually add the **using** statement at the top, save, and the error will disappear.
4. Save and return to the Editor. You should now see **Move Action** in the **Inspector** window with your arrow-key bindings.

![](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%22f5Dcpkp7DZC0QRMvpxgcJf%22%5D.body%5B_key==%22f5Dcpkp7DZC0QRMvpxgd6R%22%5D.image/Untitled%202_20260602_213206.png)

## 4. Assign bindings to the action

Now let’s add a **2D** **Vector** composite to your **Move** **Action** and bind **WASD**, while also clarifying how a **Vector2** relates to **Vector3** movement.

[Video](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%22f5Dcpkp7DZC0QRMvpxgd9U%22%5D.body%5B_key==%22c35c2bfd9a50%22%5D.overviewVideo/Unit%201.4%20-%20Step%204%20-%20Assign%20a%20binding%20to%20an%20action%20-%20FINAL%20NEW_20260625_195503.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%22f5Dcpkp7DZC0QRMvpxgd9U%22%5D.body%5B_key==%22c35c2bfd9a50%22%5D.subtitles/Unit%201.4%20-%20Step%204%20-%20Assign%20a%20binding%20to%20an%20action%20-%20FINAL%20NEW_20260625_195738.vtt))

1. In the **Inspector** window, expand the **Move Action** section, select **+ Add Binding**, then select **Add Up/Down/Left/Right Composite**. You’ll see child parts: Up, Down, Left, Right.
2. **2D Vector** outputs a Vector2 (x, y) where:
   - x comes from Left/Right (Left = -1, Right = +1)
   - y comes from Down/Up (Down = -1, Up = +1) On a keyboard it’s typically -1, 0, or +1; on analog sticks it’s a continuous range.
3. How does Vector2 relate to Vector3? For ground movement, map Vector2(x, y) to the XZ plane in 3D as Vector3(x, 0, y). That keeps vertical (Y) at 0 while moving on the plane.
4. Bind WASD:
   - Double-click **Up**, set its **Path** to keyboard/w (you can type to search or select **Listen** and press W).
   - Double-click Down, set to keyboard/s.
   - Double-click Left, set to keyboard/a.
   - Double-click Right, set to keyboard/d.
5. Repeat using **Listen** for each binding to quickly capture the key you press. Save your script/scene as needed; bindings are stored with the component.

## 5. Debug the input values

Now let’s read the **Move** **Action** as a **Vector2** and expose it in the **Inspector** window so you can see input values live in Play mode.

[Video](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%22f5Dcpkp7DZC0QRMvpxge5P%22%5D.body%5B_key==%22f5Dcpkp7DZC0QRMvpxgeBV%22%5D.overviewVideo/Unit%201.4%20-%20Step%205%20-%20Debug%20the%20input%20values%20-%20FINAL%20NEW_20260625_195805.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%22f5Dcpkp7DZC0QRMvpxge5P%22%5D.body%5B_key==%22f5Dcpkp7DZC0QRMvpxgeBV%22%5D.subtitles/Unit%201.4%20-%20Step%205%20-%20Debug%20the%20input%20values%20-%20FINAL%20NEW_20260625_195950.vtt))

1. In **PlayerController.cs,** add a public **Vector2,** named **moveInput**.
2. Inside the **Start** method, use **moveAction.Enable();**
3. At the beginning of the **Update** method, add **moveInput = MoveAction.ReadValue\<Vector2>();**, then save and return to Unity.
4. Enter Play mode, select your **Player** in the **Hierarchy** window, and watch **moveInput** in the **Inspector** window change as you press WASD/Arrow keys (x = left/right, y = forward/back).
5. How we’ll use these values:
   - Strafing-style movement: use **moveInput** directly on the XZ plane as **Vector3(moveInput.x, 0, moveInput.y**) multiplied by speed.
   - Steering-style movement: use moveInput.y to move forward/back and moveInput.x to rotate the vehicle around Y (turning) with turnSpeed.

![](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%22f5Dcpkp7DZC0QRMvpxge5P%22%5D.body%5B_key==%22f5Dcpkp7DZC0QRMvpxgfGZ%22%5D.image/Untitled%202_20260602_215319.png)

## 6. Make the vehicle move forward and sideways

Now let’s drive movement using the **Move** **Action**’s **Vector2** by multiplying your **Translate** calls with **moveInput.x** and **moveInput.y**.

[Video](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%22c5cad8e0e62d%22%5D.body%5B_key==%22a99744e75890%22%5D.overviewVideo/Unit%201.4%20-%20Step%206%20-%20Make%20the%20vehicle%20move%20forward%20and%20sideways%20-%20FINAL%20NEW_20260625_200015.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%22c5cad8e0e62d%22%5D.body%5B_key==%22a99744e75890%22%5D.subtitles/Unit%201.4%20-%20Step%206%20-%20Make%20the%20vehicle%20move%20forward%20and%20sideways%20-%20FINAL%20NEW_20260625_200117.vtt))

1. In **PlayerController.cs**, update your movement to use **moveInput.y** for forward/back and **moveInput.x** for left/right.
2. **moveInput.y** is the vertical axis of the 2D Vector (Up/Down). We map it to forward/back movement on Z. moveInput.x is the horizontal axis (Left/Right), mapped to movement on X.
3. Enter **Play Mode** and test forward/back with W/S or Up/Down.
4. Now test left/right with A/D or Left/Right. If it doesn’t move, your turnSpeed is likely 0 in the Inspector.
5. Set **turnSpeed** to a non-zero value like 5 in the Inspector, then enter Play Mode again.


![](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%22c5cad8e0e62d%22%5D.body%5B_key==%225fc1f9d21eb6%22%5D.image/Untitled%207_20260618_223002.png)

## 7. Make the vehicle turn instead of sliding

Now replace the sideways Translate with a Rotate so the player steers around the Y axis.

[Video](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%222c070543eb4b%22%5D.body%5B_key==%22493a03b41343%22%5D.overviewVideo/Unit%201.4%20-%20Step%207%20-%20Make%20the%20vehicle%20turn%20instead%20of%20sliding%20-%20FINAL%20NEW_20260625_200134.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%222c070543eb4b%22%5D.body%5B_key==%22493a03b41343%22%5D.subtitles/Unit%201.4%20-%20Step%207%20-%20Make%20the%20vehicle%20turn%20instead%20of%20sliding%20-%20FINAL%20NEW_20260625_200348.vtt))

1. In PlayerController.cs, add this line at the end of the Update() function **transform.Rotate(Vector3.up, Time.deltaTime \* turnSpeed \* moveInput.x);**
2. Now delete this line **transform.Translate(Vector3.right \* Time.deltaTime \* turnSpeed \* moveInput.x);**
3. How Rotate works:
   - **transform.Rotate(Vector3.up, angle)** spins the object around its local Y axis (up) by “angle” degrees.
   - Here, angle = **Time.deltaTime** × **turnSpeed** × **moveInput.x**, so rotation is frame-rate independent and scaled by your input (−1 to +1).
   - Positive x input turns right; negative turns left.

![](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%222c070543eb4b%22%5D.body%5B_key==%22f45e9b86369f%22%5D.image/S7_20260602_215552.png)

## 8. Clean your code and Hierarchy

Now let’s improve readability with comments and make the input Vector2 private, since it’s only used internally.

[Video](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%22cb603d80f9e9%22%5D.body%5B_key==%22976776256bb3%22%5D.overviewVideo/Unit%201.4%20-%20Step%208%20-%20Clean%20your%20code%20and%20Hierarchy%20-%20FINAL%20NEW_20260625_200405.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%22cb603d80f9e9%22%5D.body%5B_key==%22976776256bb3%22%5D.subtitles/Unit%201.4%20-%20Step%208%20-%20Clean%20your%20code%20and%20Hierarchy%20-%20FINAL%20NEW_20260625_200530.vtt))

1. Use **//** to add comments to each section of code.
2. Change `moveInput` to a private field.

![](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/c812dbbe-c995-4ad4-b50b-d4fc43bf95b9/versions%5B_key==%2292c957ee44fd%22%5D.sections%5B_key==%22cb603d80f9e9%22%5D.body%5B_key==%227a539ffb9048%22%5D.image/Step%208_20260602_220008.png)

## 9. Lesson Recap

## New Functionality

- When the player presses the up/down arrows, the vehicle will move forward and backward
- When the player presses the left/right arrows, the vehicle turns

## New Concepts & Skills

- Empty objects
- Get user input
- Translate vs Rotate

## Check your script

```csharp
using UnityEngine;
using UnityEngine.InputSystem;

public class PlayerController : MonoBehaviour
{
    public float speed = 5.0f;     
    public float turnSpeed = 100f;   

    public InputAction MoveAction;

    private Vector2 moveInput;

    void Start()
    {
        MoveAction.Enable();
    }

    void Update()
    {
        moveInput = MoveAction.ReadValue<Vector2>();

        transform.Translate(Vector3.forward * Time.deltaTime * speed * moveInput.y);

        transform.Rotate(Vector3.up, Time.deltaTime * turnSpeed * moveInput.x);
    }
}
```
