Massaging thumbsticks

Gamepad thumbsticks return floating point values ranging from -1 to 1. It can be tempting to hook these inputs directly up to your physics, writing code like:

    turn += gamepad.ThumbSticks.Left.X * turnRate;

But wait! Are you sure this is really what you want? Good analog control has a huge impact on the feel of a game, and massaging your input values can do wonders to make things feel more controllable and responsive.

I like to apply a power curve to my analog inputs:

    const float power = 3;

    turn += PowerCurve(gamepad.ThumbSticks.Left.X) * turnRate;

    float PowerCurve(float value)
        return (float)Math.Pow(Math.Abs(value), power) * Math.Sign(value);

This response curve makes small input values even smaller, allowing for more precise control, but still preserves the full range when you move the stick to an extreme position:

In effect, it makes analog inputs feel even more analog than they normally would. Higher power values make the curve more pronounced, while smaller ones make it more subtle: somewhere around 2 or 3 is usually good.

Setting the power to 1 turns the curve into a no-op, while fractional values reverse the effect, making the controls feel more discrete and digital:

Comments (6)

  1. Ultrahead says:

    Weird title, great advice …

  2. Mykres Space says:

    Here we go again with another weekly update; sorry it is a bit late. But it as been another quiet week

  3. Here we go again with another weekly update; sorry it is a bit late. But it as been another quiet week in the world of XNA, but this week we have seen a few new Bloggers come onto the scene (Lets hope they keep the content flowing). We have also seen

  4. jasond says:

    Great advice. Just a note to be careful about implementing this in multidirectional movement, where you don't have 2 dimension meaning two different things (say, steer and accelerate), but a total 2D field that implies the amount of motion of a character.  If you apply this power curve to each dimension individually, you'll find trouble moving away from orthogonal directions, and this is wrong.  It seems the proper thing to do in this case would be to apply it to the movement vector itself (its magnitude / length).

  5. Josh says:

    What program did you use to make those graphs?

Skip to main content