Game design2 min read

Why your mobile joystick feels wrong

Three numbers decide whether an on-screen joystick feels sharp or mushy: the dead zone, the travel radius and where the stick’s centre sits. How to tune each one.

Players never write “the dead zone is too small” in a review. They write “the controls feel bad”, and then they uninstall. Nearly every on-screen joystick I’ve had to fix came down to the same three numbers, and none of them can be judged with a mouse in the Editor.

The dead zone: ignore the thumb’s wobble

A resting thumb is never perfectly still. Without a dead zone the character creeps around on its own. The usual fix — treat any input below 20% as zero — creates a new problem: the moment the thumb crosses the line, output jumps from 0 straight to 0.2, and fine movement becomes impossible.

Remap the rest of the range instead, so output starts from zero at the edge of the dead zone:

C#
static Vector2 ApplyDeadZone(Vector2 input, float deadZone)
{
    float magnitude = input.magnitude;
    if (magnitude <= deadZone) return Vector2.zero;

    // 0 at the dead zone's edge, 1 at the rim: no jump, full range.
    float scaled = Mathf.InverseLerp(deadZone, 1f, Mathf.Min(magnitude, 1f));
    return input / magnitude * scaled;
}

It’s radial, too: checking x and y separately creates a square dead zone that makes diagonals feel sticky. Somewhere between 0.1 and 0.15 of the radius is a good place to start.

Travel: measure it in millimetres, not pixels

How far the thumb must move to reach full speed is a physical distance. Size it in pixels and it feels twitchy on a small phone and sluggish on a tablet. Screen.dpi converts, with a fallback for the devices that report zero:

C#
// About 11 mm of travel, whatever the screen.
float radius = Screen.dpi > 0 ? 0.45f * Screen.dpi : Screen.height * 0.12f;

The centre: fixed, floating or dynamic

A fixed stick sits in one place, so the thumb has to find it without looking. A floating stick puts its centre wherever the thumb first lands, which most players prefer in action games. A dynamic stick goes one step further and drags its centre along when the thumb travels past the rim, so reversing direction is instant instead of a long slide back:

C#
Vector2 delta = touch - center;
if (delta.magnitude > radius) center = touch - delta.normalized * radius;
Vector2 input = (touch - center) / radius;

Test with a thumb, not a mouse

A mouse is precise and a thumb isn’t. The Device Simulator is fine for layout, but tune the feel on a real phone, in both hands, on the smallest and the largest screen you support. Watch someone else play without telling them anything: if they keep re-planting their thumb, the stick is too small or fixed in the wrong place.

  • Input
  • Mobile
  • Game feel

Written by

Logical Programmer

Solo indie developer. I build games in Unity, ship them on Google Play, and document all of it.

Built with this package

Input

510 sales

Mobile Joystick Kit

Fixed & floating on-screen joystick. Multi-touch, custom deadzone, New Input System ready.

$14.99was $24.99Save $10

Details

Checkout

Online checkout opens soon

Need Mobile Joystick Kit today? Email me and I’ll sort out payment and the download for you.

Mobile Joystick Kit$14.99

Keep reading

All articles
  • Tutorial2 min read

    Object pooling in Unity, the built-in way

    Unity has shipped a generic object pool since 2021. How to use UnityEngine.Pool properly: prewarming, resetting state, and the one mistake that corrupts a pool.

    Read

  • Tutorial2 min read

    Save files that survive your next update

    Every update that changes your save format can wipe a player’s progress. A version number, one migration step per version and a safe write stop it from ever happening.

    Read

  • Tutorial2 min read

    Enemy AI you can read at a glance

    A finite state machine in plain C#: patrol, chase and search as small classes, with every transition in one place. No behaviour tree required.

    Read