Skip to main content

Making a character Jump using the Input System and a Character Controller

This lesson build on the code from the Moving a Player lesson, please make sure that you have completed that lesson first.

This is a long video and will take a while to complete but introduces useful concepts like adding in your own bindings to the input map.

Note replace the Update method with FixedUpdate.

https://www.youtube.com/watch?v=cnSqgA4OIEk&ab\_channel=LearnICTNow

This guide assumes that you have movement already setup on the player object.

Add a Jump action to the existing InputActions for the player.

Create a new C# script for jumping. This example is called PlayerJump. Alternatively you can add this code to the movement script.

We need to setup some variables to handle jumping.

These are the vertical velocity, the gravity and the default jump height. These are shown on lines 9-12 below.

On line 4 we have also imported the Input System package.

Line 15 assigns the character controller to the variable.

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

public class PlayerJump : MonoBehaviour
{

public float velocity = 0;
public float gravity = 9.8f;
public float jumpHeight = 4;
public CharacterController characterController;

void Start() {
characterController = GetComponent<CharacterController>();
}

void Update()
{

}

}

Next we will add in code that will run when the jump button is pressed.

We create the OnJump() method (this will be the name of the action in the Input Actions with On in front of it. This is shown on line 23.

We then need to detect if the player (the character controller) is on the ground. The character controller has a variable that stores this called isGrounded. Line 25 checks if the player is grounded (and can then jump). We then set the velocity to the square root of the default jumpheight * the gravity. This is on line 26.

Lines 27 and 29 have debug messages to help with detecting if the jump button has been pressed.

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

public class PlayerJump : MonoBehaviour
{

public float velocity = 0;
public float gravity = 9.8f;
public float jumpHeight = 4;
public CharacterController characterController;

void Start() {
characterController = GetComponent<CharacterController>();
}

void Update()
{

}

void OnJump() {

if(characterController.isGrounded) {
velocity = Mathf.Sqrt(jumpHeight * (gravity));
Debug.Log("Jump pressed");
} else {
Debug.Log("Jump not allowed");
}
}
}

Next we need to actually move the player.

To do this we have created a method MovementJump(), we call this from the Update() method as shown on line 20.

The MovementJump() method covers lines 33-38.

To jump we first slightly decrease the velocity to give the jump an arc. This is done on line 34.

The player is moved on line 35.

Finally on lines 36-38 we check if we have landed on the ground again and reset velocity to 0 if we have.

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

public class PlayerJump : MonoBehaviour
{

public float velocity = 0;
public float gravity = 9.8f;
public float jumpHeight = 4;
public CharacterController characterController;

void Start() {
characterController = GetComponent<CharacterController>();
}

void Update()
{
MovementJump();
}

void OnJump() {

if(characterController.isGrounded) {
velocity = Mathf.Sqrt(jumpHeight * (gravity));
Debug.Log("Jump pressed");
} else {
Debug.Log("Jump not allowed");
}
}

void MovementJump() {
velocity -= jumpHeight * gravity * Time.deltaTime;
characterController.Move(new Vector3(0, velocity, 0));
if(characterController.isGrounded) {
velocity = 0;
}

}
}

We not have a completed

Alternative Jump Code Example

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

[RequireComponent(typeof(CharacterController))]
public class PlayerJump : MonoBehaviour
{
// Player variables
private CharacterController _characterController;

// Jumping variables
private Vector3 _playerVelocity;
private bool _groundedPlayer;
[SerializeField] private float _jumpHeight = 5.0f;
private bool _jumpPressed = false;
private float _gravityValue = -9.81f;

// Start is called before the first frame update
void Start()
{
_characterController = GetComponent<CharacterController>();
}

// Update is called once per frame
void FixedUpdate()
{
MovementJump();
}

// Handle the player movement and update the player on the scene.
void MovementJump() {
// Check if the player is grounded
_groundedPlayer = _characterController.isGrounded;
if (_groundedPlayer)
{
_playerVelocity.y = 0f; // If they're on the ground their vertical velocity is 0.
}

// Changes the height position of the player..
if (_jumpPressed && _groundedPlayer)
{
_playerVelocity.y += Mathf.Sqrt(_jumpHeight * -3.0f * _gravityValue); // Move the player in a nice parabola for the jump
_jumpPressed = false; // We've handled the jump so turn off the flag for the pressing of the button
}

_playerVelocity.y += _gravityValue * Time.deltaTime; // Update the player velocity (decreasing over time)
_characterController.Move(_playerVelocity * Time.deltaTime); // Move the player
}

// Run when the jump button is pressed
private void OnJump() {
Debug.Log("Jump Pressed");


// If on the ground let them jump
if(_characterController.velocity.y == 0) {
Debug.Log("Can jump");
_jumpPressed = true;
} else {
Debug.Log("Can't jump - free falling!");
}
}
}