Configurable-radius deadzone for thumbsticks in XNA

Yesterday, while co-working at The MADE (a cool game museum that lets Bay Area developers work out of some of their space), the topic of thumbstick deadzones came up. Ian Stocker mentioned that he had recently made a blog post about using the Xbox analog sticks as a DPad in XNA.

Since Hive deals with hexagons, I didn’t do my implementation quite the same. The deadzone code I used is separate from the code for getting directions, so it should work regardless of what your game is using the thumbsticks for.

We discussed the methods that we used for adding a “deadzone” to the analog sticks. A deadzone is the area near the center of the stick where you ignore input because slight movements (or even old controllers while their sitting still) could trigger unintended input otherwise. He explained that his deadzone was square and thought that people might benefit from my code which makes a circular dead-zone, so here it is!

I did the entry-level trigonometry so that you don’t have to! 😉

Example usage of the thumbstick “deadzone” code.
[crayon lang=”c#”]
PlayerIndex playerOne = PlayerIndex.One;
GamePadState gamePadState = GamePad.GetState(playerOne);
Vector2 leftThumbstickState = gamePadState.ThumbSticks.Left;
if ( ThumbstickMovementIsSignificant(leftThumbstickState) )
{
// Actually use the leftThumbstickState.
}
[/crayon]

And this is the general code that I put in my GamePadHelper.cs.
[crayon lang=”c#”]
///

/// Returns true if the movement is significant, false if the movement was so slight
/// that it shouldn’t be counted. This uses a reasonable default for how much to ignore.
///
///

/// ///
public static bool ThumbstickMovementIsSignificant(Vector2 thumbstickState)
{
float percentToIgnore_default = 35.0f;
return ThumbstickMovementIsSignificant(thumbstickState, percentToIgnore_default);
}

///

/// Determines if the thumbstickState passed in is significant enough, given the constraint
/// of how much movement should be ignored.
///

/// /// Percentage of the unit-circle which is ignored. If 25.0f, then the inner-quarter of movements will be considered too slight. If 50.0f, then the inner half will be ignored, etc.. public static bool ThumbstickMovementIsSignificant(Vector2 thumbstickState, float percentToIgnore){
bool isSignificant = true;
if (percentToIgnore > 0)
{
// Uses pythagorean theorem to see if the hypotenuse ends inside of the “significant” area or not.
float a = thumbstickState.X;
float b = thumbstickState.Y;

// Thumbstick numbers are in a unit-circle so scale the percentToIgnore to the range of 0.0 to 1.0
float minHyphotenuseLengthForSignificance = (percentToIgnore / 100);

// This function is likely to be called every tick, so we square the minimum hyptotenuse instead of comparing it the sqrt of a^2 + b^2 (square roots are a bit slow).
if (((a * a) + (b * b)) < (minHyphotenuseLengthForSignificance * minHyphotenuseLengthForSignificance)) { isSignificant = false; } } return isSignificant; } [/crayon] I haven't played around with the thumbsticks that much, so I'm not sure how big of a deadzone is ideal. I stuck with the default of percentToIgnore_default = 35.0f;, which means that the inner 35% of the thumbstick’s radius is ignored. Feel free to tweak the default or pass in a custom value as the second parameter to ThumbstickMovementIsSignificant().

Hope the code is helpful! 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *