Tap & Hold with New Unity Input System

Simon Pham
3 min readJan 17, 2024

--

In today’s blog post, we’ll explore how to set up the tap-and-hold feature using the New Unity Input System, a commonly used element in many video games. For instance, you can hold to fire charged shots in the Mega Man video games or launch birds from a slingshot in the Angry Birds series. For the purpose of demonstration, we’ll create a ball that, upon tapping a button, performs a little hop. The longer you hold the button, the higher the ball will jump in the air.

Bouncing Ball

Creating Action Map and Action

Firstly, let’s set up a simple scene including a Floor (represented by a Plane) and a Ball (represented by a Sphere). Additionally, we’ll need to attach a Rigidbody to the Ball to be able to apply physics to it.

The Rigidbody Component of the Ball

Next, let’s create a new Action Map for the Ball and an Action called “Bounce”.

Action Map and Action for the Ball

I want the ball to bounce when I press the J key. Additionally, I want to be able to make the ball jump by tapping the key, so I’m going to set the press point to 0.2 seconds.

Scripting

After finishing the setup of the Action Map, let’s create a C# script for the ball. First, we need to enable the new Action Map and its action. Since I want the ball to bounce when releasing the button, I’m going to access the “canceled” callback.

private PlayerInputActions _input;
private void Start()
{
_input = new PlayerInputActions();
_input.Ball.Enable();
_input.Ball.Bounce.canceled += Bounce_canceled;
}
private void Bounce_canceled(InputAction.CallbackContext context)
{
//TODO: Tap and hold to make the ball bounce
}

Now, let’s move on to the physics part. To make the ball bounce, I’ll use the AddForce method, which requires two parameters: a Vector3 and ForceMode. For the Vector3 component, I’ll use Vector3.up multiplied by a jump force of 300f and the time the key is held. As for the ForceMode parameter, there are four modes (Acceleration, Force, Impulse, and VelocityChange), and I’ll choose ForceMode.Force.

Since the height of the ball’s bounce depends on the hold time, I want to limit it between 0.5 and 2 seconds. This way, the ball can make small hops when we tap the key and won’t jump too high when we hold the key for too long.

private float _jumpForce = 300f;
private Rigidbody _rb;
private void Start()
{
_rb = GetComponent<Rigidbody>();
if( _rb == null)
{
Debug.LogError("Rigidbody is null");
}
}
private void Bounce_canceled(InputAction.CallbackContext context)
{
float holdTime = (float)context.duration;
if( holdTime < 0.5f )
{
holdTime = 0.5f;
} else if (holdTime > 2f)
{
holdTime = 2f;
}
_rb.AddForce(Vector3.up * _jumpForce * holdTime, ForceMode.Force);
}

And here’s the full code:

using UnityEngine;
using UnityEngine.InputSystem;

public class Ball : MonoBehaviour
{
private PlayerInputActions _input;
private float _jumpForce = 300f;
private Rigidbody _rb;

private void Start()
{
_rb = GetComponent<Rigidbody>();
if( _rb == null)
{
Debug.LogError("Rigidbody is null");
}

_input = new PlayerInputActions();
_input.Ball.Enable();
_input.Ball.Bounce.canceled += Bounce_canceled;
}

private void Bounce_canceled(InputAction.CallbackContext context)
{
float holdTime = (float)context.duration;
if( holdTime < 0.5f )
{
holdTime = 0.5f;
} else if (holdTime > 2f)
{
holdTime = 2f;
}
_rb.AddForce(Vector3.up * _jumpForce * holdTime, ForceMode.Force);
}
}

--

--