Quick answer: Configure a Stick Deadzone processor on your analog stick Input Actions with Min=0.125 and Max=0.925, use radial (magnitude-based) dead zones rather than per-axis ones, and expose the value as a user setting so players with drifting sticks can increase it. Never rely on the default without testing on real controllers of varying ages.

“My character keeps walking on its own” is one of the most frustrating bug reports to receive because it sounds like a game-breaking AI bug, when it’s almost always a controller dead zone issue. Analog sticks drift, and if your game doesn’t filter out small values around the resting position, every micro-deflection becomes input. Here’s how to diagnose these bugs from player reports and fix them in Unity’s Input System.

Symptoms of a Dead Zone Bug

Dead zone bugs generate very specific kinds of player complaints. If you see any of these, stick drift is your first suspect:

The giveaway is that the issue is usually controller-specific. One player on a brand-new DualSense is fine, another player on an Xbox One controller from 2015 has the character drifting. That difference across hardware is the signature of a dead zone problem rather than a game logic bug.

Step 1: Visualize the Raw Input

Before tuning dead zones, see the actual values your input is producing. Add a debug overlay that shows the raw x/y values from both sticks in real time. You’ll immediately see drift — a stick at rest might report (0.06, -0.04) instead of (0, 0), and during slow movement might reach (0.3, 0.0).

using UnityEngine;
using UnityEngine.InputSystem;

public class DebugInputOverlay : MonoBehaviour
{
    private Vector2 leftStick;
    private Vector2 rightStick;

    void Update()
    {
        var gamepad = Gamepad.current;
        if (gamepad == null) return;
        leftStick = gamepad.leftStick.ReadValue();
        rightStick = gamepad.rightStick.ReadValue();
    }

    void OnGUI()
    {
        GUI.color = Mathf.Abs(leftStick.x) > 0.01f || Mathf.Abs(leftStick.y) > 0.01f
            ? Color.red : Color.white;
        GUI.Label(new Rect(10, 10, 400, 20),
            $"Left: ({leftStick.x:F3}, {leftStick.y:F3})  mag={leftStick.magnitude:F3}");
        GUI.Label(new Rect(10, 30, 400, 20),
            $"Right: ({rightStick.x:F3}, {rightStick.y:F3})  mag={rightStick.magnitude:F3}");
    }
}

With the overlay running, let the sticks rest untouched. Any non-zero reading is drift. Move the sticks slowly to their edges and back. You’ll see non-linear behavior — usually the sticks reach 1.0 before you push all the way, and come back with some residual on release. That’s your noise floor and your dead zone must clear it.

Step 2: Apply a Radial Dead Zone

Unity’s Input System provides a Stick Deadzone processor that does the right thing: it computes the magnitude of the stick vector and ignores anything below a minimum threshold, then linearly scales the remaining range back to full. This preserves circular movement characteristics and doesn’t snap to cardinal directions.

Open your Input Actions asset, find your Move or Look action, click the stick binding, and add a processor. Pick Stick Deadzone, not Axis Deadzone. Set:

// Alternatively, apply the dead zone in code
using UnityEngine.InputSystem;

public static Vector2 ApplyRadialDeadzone(Vector2 input, float min = 0.125f, float max = 0.925f)
{
    float magnitude = input.magnitude;
    if (magnitude < min) return Vector2.zero;
    if (magnitude > max) return input.normalized;

    // Rescale so that min becomes 0 and max becomes 1
    float rescaled = (magnitude - min) / (max - min);
    return input.normalized * rescaled;
}

Why Axial Dead Zones Are Wrong

The old-school approach is to apply a dead zone to each axis independently: if abs(x) < 0.125, set x = 0; same for y. This sounds equivalent but produces a terrible feel. When you push the stick diagonally at low magnitudes, one axis crosses its threshold before the other, so your diagonal movement starts as pure horizontal, then snaps to diagonal, then back. Characters feel sticky at low speeds and the direction snaps to cardinal axes.

Radial dead zones don’t have this problem because they check the total magnitude, not each axis. Players feel smooth, proportional control in any direction. If you have existing code that uses per-axis thresholds, rewrite it.

Step 3: Expose Dead Zone as a Setting

Controllers age. An Xbox One controller that’s been bouncing around a coffee table for three years has a larger drift than a brand-new DualSense. No single dead zone value works for everyone. Add a slider to your options menu that lets players set their own dead zone between 0.05 and 0.35, defaulting to 0.125.

using UnityEngine;
using UnityEngine.InputSystem;

public class DeadzoneSettings : MonoBehaviour
{
    [SerializeField] private InputActionAsset inputActions;
    [SerializeField] private float currentDeadzone = 0.125f;

    public void SetDeadzone(float value)
    {
        currentDeadzone = Mathf.Clamp(value, 0.02f, 0.4f);
        ApplyToAllStickActions();
        PlayerPrefs.SetFloat("deadzone", currentDeadzone);
    }

    void ApplyToAllStickActions()
    {
        foreach (var map in inputActions.actionMaps)
        {
            foreach (var action in map.actions)
            {
                foreach (var binding in action.bindings)
                {
                    if (binding.path.Contains("Stick"))
                    {
                        var newProc = $"stickDeadzone(min={currentDeadzone},max=0.925)";
                        action.ApplyBindingOverride(new InputBinding {
                            overridePath = binding.path,
                            overrideProcessors = newProc
                        });
                    }
                }
            }
        }
    }
}

Reproducing From Bug Reports

When a player reports drift, ask them: what controller are they using, how old is it, and do they see the problem in other games. If they only see it in your game, it might genuinely be a dead zone misconfiguration. If they see it in other games too, the controller is the culprit and they need to either calibrate it, clean it, or replace it — but a larger dead zone in your game will still help them enjoy it.

For bug triage, the most useful metadata to capture is the controller model. The Input System exposes this via Gamepad.current.name — include it as a field on every bug report submitted with a gamepad connected. You’ll quickly see if your issues cluster around specific models.

Related Issues

For general input-not-working fixes, see Fix: Unity Input System Not Working. For Godot analog stick drift, see Fix: Godot Analog Stick Drift. For controller detection issues generally, see Fix: Godot Controller Gamepad Input Not Detected.

If the character moves on its own, the controller is trying to tell you something.