Reducing noise from joystick at small deflections

I have placed in my level a cube, which is my player, and a camera, which will follow the player.

I'm defining a direction A from camera to player and another B perpendicular to this one. So I get two perpendicular directions no matter where the camera is located, A and B.

So far so good. I'm multiplying the direction A by the value of the vertical axis of a PS4 joystick. And the B direction by the horizontal input.

Then I make a vector sum: C = (A * verticalInput) + (B * horizontalInput)

C faces the direction in which the player should face, regardless of the camera position, so I can move the camera anywhere and the joystick input always corresponds to the camera's view.

The issue is that when the input magnitude is very very small, the C vector oscillates rapidly in a small angle interval. The result is that the player "vibrates" when looking at that direction.

This effect disappears when the inputs are greater than 0.5, but I cannot use a value that large for a dead zone because I want my player to walk very slowly because he is a ninja! (And is about to make a stealth-kill or very slow movement to avoid noise).

In other words, how do I reduce the jitter from noisy joystick input?

• You mention that when the inputs are above 0.5 the vibrate effect disappears. What is the normal range of inputs? When the joystick is fully moved in one direction, what is the input value? Dec 18, 2019 at 21:26

At extremely small values of input values, you're essentially creating a lot of vector jitters. Even the smallest change in X or Y can have a big impact on the resultant direction vector.

Given the importance of letting your player move slowly (ninja style) at times, you would want to give them fairly good/fine control over slow motion, yet also give then the ability to move in non-ninja mode. So to do that, you should get away from requiring them to make very small joystick movements to control slower motion.

Let's assume that the joystick input values vary from 0-100, and that your player can move at a speed from 0-100. And any movement under 10 is considered "ninja movement" with special features such as a much lower chance of detection.

Given that, I'm going to suggest several methods for dealing with the input sensitivity with very low input values. It's hard to predict how this might end up working without knowing some of the more precise characteristics of the input values.

Method 1: "Ninja Mode" movement modifier

When the player holds down a modifier key (or presses it to toggle the mode), they enter "Ninja Mode", and the joystick input from 0-100 scales to movement speeds of 0-10. If they are full joystick deflection, they only move at maximum "Ninja Mode" speed. You still probably have the jitter with very tiny motion, but you also remove the requirement that the player make very tiny joystick movements to move slowly.

Method 2: Change the linear increase of joystick input values into a non-linear movement curve

Rather than a simplistic use of the input fields as you suggest, you might consider making the resultant applied input curve be non-linear. For example you might use a Sigmoid function so that a fair amount of joystick motion is required to begin movement.

Method 3: Filtering and clipping

You might find that applying some kind of moving average filter to the inputs will reduce the jitter. You can also simply reject any movement where the length of vector C is below some minimum value. Very tiny (jitter causing) movements of the joystick will be ignored because they will result in very short vector and no movement.

Of course you might also be able to combine the above suggestions in various ways for a hybrid approach.