---
title: "Lesson 3.1 - Jump Force "
content_type: tutorial
url: "https://learn.unity.com/tutorial/lesson-3-1-jump-force-2?language=en"
language: en
difficulty: beginner
duration_minutes: 90
unity_version:
  - "6.0"
  - "6.3"
supported_unity_versions:
  - name: "6.0"
    url: "https://learn.unity.com/tutorial/lesson-3-1-jump-force-2.md?language=en&version=6.0"
  - name: "6.3"
    url: "https://learn.unity.com/tutorial/lesson-3-1-jump-force-2.md?language=en&version=6.3"
  - name: "2022.3"
    url: "https://learn.unity.com/tutorial/lesson-3-1-jump-force-2.md?language=en&version=2022.3"
  - name: "2021.3"
    url: "https://learn.unity.com/tutorial/lesson-3-1-jump-force-2.md?language=en&version=2021.3"
available_languages:
  - name: "en"
    url: "https://learn.unity.com/tutorial/lesson-3-1-jump-force-2.md?language=en"
  - name: "es"
    url: "https://learn.unity.com/tutorial/leccion-3-1-fuerza-de-salto.md?language=es"
  - name: "ja"
    url: "https://learn.unity.com/tutorial/lesson-3-1-jump-force-jp.md?language=ja"
  - name: "ko"
    url: "https://learn.unity.com/tutorial/3-1gang-jeompeuryeog.md?language=ko"
last_updated: "2026-08-04T14:23:41.000Z"
---

# Lesson 3.1 - Jump Force 

Build a simple runner prototype where a player character jumps over spawning obstacles using a spacebar-controlled setup.

**Overview:**

The goal of this lesson is to set up the basic gameplay for this prototype. We will start by creating a new project and importing the starter files. Next we will choose a beautiful background and a character for the player to control, and allow that character to jump with a tap of the spacebar. We will also choose an obstacle for the player, and create a spawn manager that throws them in the player’s path at timed intervals.

**Project Outcome:**

The character, background, and obstacle of your choice will be set up. The player will be able to press spacebar and make the character jump, as obstacles spawn at the edge of the screen and block the player’s path.

Overview: [Video](https://connect-mediagw.unity.com/h1/20241203/videos/18206d41-5fcb-4b47-8faa-9606eadd7ab1_CWC_U3.L1.S0_U6.mp4) ([Transcript (en)](https://connect-mediagw.unity.com/h1/20241203/3b1291bd-0e12-46df-8086-85157fbed12f_CWC_U3.L1.S0_U6.mp4.vtt))

## Materials

- [Prototype 3 - Starter Files](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.materials%5B_key==%221a989f0ab8d1%22%5D.file/Prototype-3_Starter-Files_U6_20260612_223049.unitypackage)

## 1. Open prototype & change background

The first thing we need to do is set up a new project, import the starter files, and choose a background for the game.

[Video](https://connect-mediagw.unity.com/h1/20241204/videos/606b139d-c23b-465c-aa36-980d46b8f5f5_CWC_U3.L1.S1_U6.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vEfK%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vEmU%22%5D.subtitles/CWC_U3.L1.S1_U6.mp4_20260505_043335.srt))

1. Open **Unity Hub** and create an empty “Prototype 3” project in your course directory on the correct Unity version.
   If you forget how to do this, refer to the instructions in [Lesson 1.1 - Step 1](https://learn.unity.com/course/create-with-code/unit/unit-1-driving-simulation/tutorial/lesson-1-1-start-your-3d-engines?version=6.0#674f41a1edbc2a1e806fc55b).
2. Click to download the [Prototype 3 Starter Files](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.materials%5B_key==%221a989f0ab8d1%22%5D.file/Prototype-3_Starter-Files_U6_20260612_223049.unitypackage), then import the **.unitypackage** into your project. For a reminder on how to create a new Unity project, you can reference [this tutorial](https://learn.unity.com/tutorial/explore-the-unity-hub?version=6.0#688a8e3bedbc2a0121d7920a).
3. Open the Prototype 3 scene and **delete** the **Sample Scene** without saving.
4. Select the **Background object** in the hierarchy, then in the **Sprite Renderer** **component > Sprite**, select the \_City, \_Nature, or \_Town image.

![](https://connect-mediagw.unity.com/h1/20231214/learn/images/840375f1-defc-44da-95ec-10f8b6a0429d_image.png)

## 2. Choose and set up a player character

Now that we’ve started the project and chosen a background, we need to set up a character for the player to control.

[Video](https://connect-mediagw.unity.com/h1/20241204/videos/3a63359b-afbf-48b9-9bd0-fec764872a95_CWC_U3.L1.S2_U6.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vGSK%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vGZU%22%5D.subtitles/CWC_U3.L1.S2_U6.mp4_20260505_043433.srt))

1. From _Course Library > Characters_, **Drag** a character into the hierarchy, **rename** **it** “Player”, then **rotate it** on the Y axis to face to the right
2. Add a **Rigid Body** component
3. Add a **Box collider**, then **edit** the collider bounds
4. Create a new “Scripts” folder in Assets,  create a “PlayerController” script inside, and **attach** it to the player

## 3. Make player jump at start

Until now, we’ve only called methods on the entirety of a gameobject or the transform component. If we want more control over the force and gravity of the player, we need to call methods on the player’s Rigidbody component, specifically.

[Video](https://connect-mediagw.unity.com/h1/20241204/videos/c49dc1cf-195d-45b9-84df-948fdea9040d_CWC_U3.L1.S3_U6.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vI8A%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vIFK%22%5D.subtitles/CWC_U3.L1.S3_U6.mp4_20260505_043446.srt))

1. In **PlayerController.cs**, declare a new **_private Rigidbody playerRb;_** variable
2. In **_Start()_**, initialize **_playerRb = GetComponent\<Rigidbody>();_**
3. In **_Start()_**, use the AddForce method to make the player jump at the start of the game

![](https://connect-mediagw.unity.com/h1/20190529/learn/images/4afd900b-4152-4d3c-abdc-992e5697784c_3.1_3.PNG)

## 4. 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.

## 5. Configure a new jump action variable

Now let’s add a Jump Action to PlayerController and bind it to the Space bar in the Inspector.

[Video](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vJ3S%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vJAc%22%5D.overviewVideo/Unit%203.1%20-%20Step%205%20-%20Configure%20a%20new%20jump%20action%20variable%20-%20FINAL%20NEW_20260625_204421.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vJ3S%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vJAc%22%5D.subtitles/Unit%203.1%20-%20Step%205%20-%20Configure%20a%20new%20jump%20action%20variable%20-%20FINAL%20NEW_20260625_204546.vtt))

1. In **PlayerController.cs**, add the **Input** **System** namespace, a public **InputAction** field, and enable it in the **Start** method:
2. In the **Inspector** window for your **Player** GameObject:
   1. Expand the **Jump** **Action** property.
   2. Select **+ Add Binding**.
   3. Set Path to keyboard/space (or select **Listen** and press **Space**).

![](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vJ3S%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vK2K%22%5D.image/Untitled%202_20260603_020209.png)

## 6. Make player jump if spacebar pressed

We don’t want the player jumping at start - they should only jump when we tell it to by pressing spacebar.

[Video](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%225ac9d254bb85%22%5D.body%5B_key==%22e24d68fbc1d3%22%5D.overviewVideo/Unit%203.1%20-%20Step%206%20-%20Make%20player%20jump%20if%20space%20is%20pressed%20%28NO%20VO%29%20-%20FINAL%20NEW_20260625_204614.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%225ac9d254bb85%22%5D.body%5B_key==%22e24d68fbc1d3%22%5D.subtitles/Unit%203.1%20-%20Step%206%20-%20Make%20player%20jump%20if%20space%20is%20pressed%20%28NO%20VO%29%20-%20FINAL%20NEW_20260625_204734.vtt))

1. In **Update()** add an **if-then statement** checking if the spacebar is pressed
2. **Cut and paste** the AddForce code from Start() into the if-statement
3. Add the **_ForceMode.Impulse_** parameter to the **_AddForce_** call, then **reduce** force multiplier value

![](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%225ac9d254bb85%22%5D.body%5B_key==%22aeefa8d40c92%22%5D.image/Untitled_20260603_021052.png)

## 7. Tweak the jump force and gravity

We need give the player a perfect jump by tweaking the force of the jump, the gravity of the scene, and the mass of the character.

[Video](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vK5u%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vKD4%22%5D.overviewVideo/Unit%203.1%20-%20Step%207%20-%20Tweak%20the%20jump%20force%20and%20gravity%20-%20FINAL%20NEW_20260625_204813.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vK5u%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vKD4%22%5D.subtitles/Unit%203.1%20-%20Step%207%20-%20Tweak%20the%20jump%20force%20and%20gravity%20-%20FINAL%20NEW_20260625_204915.vtt))

1. **Replace** the hardcoded value with a new **public float jumpForce** variable
2. Add a new **public float gravityModifier** variable and in **Start()**, add **Physics.gravity \*= gravityModifier;**
3. In the inspector, tweak the **gravityModifer**, **jumpForce**, and **Rigidbody** mass values to make it fun

![](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vK5u%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vLJ6%22%5D.image/Untitled_20260603_022016.png)

## 8. Prevent player from double-jumping

As you may have noticed, the player can spam the spacebar and send the character hurtling into the sky. In order to stop this silly exploit and make the jump more realistic, we need an if-statement that makes sure the player is grounded before they jump.

[Video](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vLMg%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vLTq%22%5D.overviewVideo/Unit%203.1%20-%20Step%208%20-%20Prevent%20the%20player%20form%20double%20jumping%20%28NO%20VO%29%20-%20FINAL%20NEW_20260625_204930.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vLMg%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vLTq%22%5D.subtitles/Unit%203.1%20-%20Step%208%20-%20Prevent%20the%20player%20form%20double%20jumping%20%28NO%20VO%29%20-%20FINAL%20NEW_20260625_205053.vtt))

1. Add a new **public bool isOnGround** variable and set it equal to **true**
2. In the if-statement making the player jump, set **isOnGround = false**, then **test**
3. Add a condition **&& isOnGround** to the **if-statement**
4. Add a new **void OnCollisionEnter** method, set **isOnGround = true** in that method, then **test**


![](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vLMg%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vMZs%22%5D.image/Untitled_20260603_022136.png)

## 9. Make an obstacle and move it left

We’ve got the player jumping in the air, but now they need something to jump over. We’re going to use some familiar code to instantiate obstacles and throw them in the player’s path.

[Video](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vMdS%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vMkc%22%5D.overviewVideo/Unit%203.1%20-%20Step%209%20-%20Make%20an%20obstacles%20and%20move%20it%20left%20%28NO%20VO%29%20-%20FINAL%20NEW_20260625_205123.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vMdS%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vMkc%22%5D.subtitles/Unit%203.1%20-%20Step%209%20-%20Make%20an%20obstacles%20and%20move%20it%20left%20%28NO%20VO%29%20-%20FINAL%20NEW_20260625_205419.vtt))

1. From _Course Library > Obstacles_, add an obstacle, rename it “Obstacle”,  and **position** it where it should spawn
2. Apply a **Rigid Body** and **Box Collider** component, then **edit** the collider bounds to fit the obstacle
3. Create a new “Prefabs” folder and drag it in to create a new **Original Prefab**
4. Create a new “MoveLeft” script, **apply** it to the obstacle, and **open** it
5. In MoveLeft.cs, write the code to **Translate** it to the left according to the speed variable
6. Apply the MoveLeft script to the **Background**

![](https://connect-mediagw.unity.com/h1/20190529/learn/images/60af2eb2-0332-45eb-be29-c72108019604_3.1_7.PNG)

## 10. Create a spawn manager

Similar to the last project, we need to create an empty object Spawn Manager that will instantiate obstacle prefabs.

[Video](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vObC%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vOiM%22%5D.overviewVideo/Unit%203.1%20-%20Step%2010%20-%20Create%20a%20spawn%20manager%20%28NO%20VO%29%20-%20FINAL%20NEW_20260625_205449.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vObC%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vOiM%22%5D.subtitles/Unit%203.1%20-%20Step%2010%20-%20Create%20a%20spawn%20manager%20%28NO%20VO%29%20-%20FINAL%20NEW_20260625_205859.vtt))

1. Create a new “Spawn Manager” empty object, then apply a new **SpawnManager.cs** script to it
2. In **SpawnManager.cs**, declare a new **public GameObject obstaclePrefab;**, then **assign** your prefab to the new variable in the inspector
3. Declare a new **private Vector3 spawnPos** at your spawn location
4. In **Start()**, **Instantiate** a new obstacle prefab, then **delete** your prefab from the scene and test

![](https://connect-mediagw.unity.com/h1/20190529/learn/images/1f74a89b-4926-46f8-9d8f-5c2501df76ba_3.1_8.PNG)

## 11. Spawn obstacles at intervals

Our spawn manager instantiates prefabs on start, but we must write a new function and utilize **InvokeRepeating** to spawn obstacles on a timer. Lastly, we must modify the character’s RigidBody so it can’t be knocked over.

[Video](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vQ6I%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vQDS%22%5D.overviewVideo/Unit%203.1%20-%20Step%2011%20-%20Spawn%20obstacles%20at%20intervals%20%28NO%20VO%29%20-%20FINAL%20NEW_20260625_205938.mp4) ([Transcript (en)](https://storage.googleapis.com/learn-platform-bucket-production/tutorial/a93dd212-9ead-4665-be25-1a469ce414c1/versions%5B_key==%2275e51555a88a%22%5D.sections%5B_key==%22s9Hg5o7FgxN04KocM6vQ6I%22%5D.body%5B_key==%22s9Hg5o7FgxN04KocM6vQDS%22%5D.subtitles/Unit%203.1%20-%20Step%2011%20-%20Spawn%20obstacles%20at%20intervals%20%28NO%20VO%29%20-%20FINAL%20NEW_20260625_210200.vtt))

1. Create a new **void SpawnObstacle** method, then move the **Instantiate** call inside it
2. Create new **float variables** for **startDelay** and **repeatRate**
3. Have your obstacles spawn on **intervals** using the **InvokeRepeating()** method
4. In the Player Rigid Body component, expand **Constraints**, then **Freeze** all but the Y position

![](https://connect-mediagw.unity.com/h1/20190529/learn/images/40062f1c-4fc6-4dd9-8884-8adc9e603a9b_3.1_9.PNG)

## 12. Lesson Recap

## New Functionality

- Player jumps on spacebar press
- Player cannot double-jump
- Obstacles and Background move left
- Obstacles spawn on intervals

## Key Concepts and Skills

- GetComponent
- ForceMode.Impulse
- Physics.Gravity
- Rigidbody constraints
- Rigidbody variables
- Booleans
- Multiply/Assign (“\*) Operator
- And (&&) Operator
- OnCollisionEnter()

## Next Lesson

- We’re going to fix that weird effect we created by moving the background left by having it actually constantly scroll using code!

## Check your scripts

PlayerController.cs

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

public class PlayerController : MonoBehaviour
{
    private Rigidbody playerRb;
    public InputAction jumpAction;
    public float jumpForce = 10;
    public float gravityModifier;
    public bool isOnGround = true;

    void Start()
    {
        playerRb = GetComponent<Rigidbody>();
        jumpAction.Enable();
        Physics.gravity *= gravityModifier;
    }

    void Update()
    {
        if (jumpAction.triggered && isOnGround)
        {
            playerRb.AddForce(Vector3.up * jumpForce, ForceMode.Impulse);
            isOnGround = false;
        }
    }

    private void OnCollisionEnter(Collision collision)
    {
        isOnGround = true;
    }
}
```

MoveLeft.cs

```csharp
using UnityEngine;

public class MoveLeft : MonoBehaviour
{
    private float speed = 30;

    void Update()
    {
        transform.Translate(Vector3.left * Time.deltaTime * speed);
    }
}
```

SpawnManager.cs

```csharp
using UnityEngine;

public class SpawnManager : MonoBehaviour
{
    public GameObject obstaclePrefab;
    private Vector3 spawnPos = new Vector3(25, 0, 0);
    private float startDelay = 2;
    private float repeatRate = 2;

    void Start()
    {
        InvokeRepeating("SpawnObstacle", startDelay, repeatRate);
    }

    void Update()
    {
        
    }

    void SpawnObstacle()
    {
        Instantiate(obstaclePrefab, spawnPos, obstaclePrefab.transform.rotation);
    }
}
```
