How to smooth analog input values in real time?

By default, Unreal Engine reads the exact and precise values of an analog stick. This, if “Orient Rotation To Movement” is active, causes jittery rotation when using a controller, since all the tiny changes in the thumbstick value affect the movement.

How could i make these values smooth? Should i use interpolation? Should i change something in the deadzone settings? And if the answer is interpolation, how could i divide the analog stick in just, let’s say, 8 valid input directions to interpolate between eachother? Should i do this math in a separate UPlayerInput class or should i implement this in my Character class?Nobody seems to adress this, i haven’t found anyone with a solution, yet.

Here’s a video i made showing what smooth rotation looks like compared to the default Unreal Engine:

“Smooth” refers to how the present value compares to the past and the future.

We are 3.5 dimensional creatures crawling through 4 dimensions - we have no access to the future, so we must smooth using past data.

There are a bunch of techniques on that page, and it depends on how “responsive” you want it to be. Adding half the difference between current and previous value could be the simplest thing that could possibly work.

As an alternative, you might find that the physics system on the pawn can simulate an “intertia” that dampens erratic inputs, creating the illusion, of the illusion, of smoothing :slight_smile:

I think a more specific answer depends on the genre and personal preference through experimentation.

Thanks for the useful information. It sounds like a ton of work, but i guess i’ll figure it out at some point.

Looking at the videos, the sword lady appears to hit her max turning radius - she could go in tighter circles but doesn’t. The unreal guy doesn’t appear to hit that “pegged” max, and instead jitters near the top.

In the running videos, the UE4 guy definitely appears massless. Whatever force is turning him is massive and instant acceleration. The sword lady has a bit more of a ship to steer, which shows off her animations (tassle on her sword, etc).

I wish I could be more help :slight_smile:

You might find this interesting: Addforce and addimpulse - C++ Programming - Unreal Engine Forums

Oh, you mean physics based movement? Now that i think about it, the code for the movement is currently just “AddMovementInput(Direction, Value);” which does seem to be an instant infinite force.

TO ANYONE THAT MIGHT RUN INTO THE SAME PROBLEM:

The solution is to use FMath::WeightedMovingAverage, a built in smoothing function, on the value you will be using on “AddMovementInput(Direction, Value)”.

IT DOESN’T END HERE THO!
This smoothing function doesn’t get along with controller deadzones, so make sure you set you thumbsticks’ deadzone to 0.

Then, using a global variable of type FVector or FVector2D, create a vector that takes in the X and Y values of the single thumbstick (because UE4 separates them into 2 different readings, thus 2 movement functions: one for the forward movement and one for the lateral movement).

Then get the Size (or length) of that vector, and that will be how much you’re pushing your thumbstick in any direction.
Make an if statement that goes like “if (VectorSize > 0.25) //do the movement stuff” 0.25 being the value of the deadzone.

After all this, if you use FMath::WeightedMovingAverage in the right way, which is a little complex but not too much (there’s documentation around) you will have a very smooth character rotation. You can change the amount of the smoothing by changing the “Weight” of the WeightedMoveingAverage function, which is one of the 3 parameters.

THANKS TO THE PERSON THAT REPLIED TO THIS QUESTION FIRST! THEY GUIDED ME IN THE RIGHT DIRECTION TO FIND THE SOLUTION!

Did you mark your answer correct and then ask me another question bro?! LOL. You want to store previous sample as a variable and keep feeding in the previous result from the function

Hi @FunAndFriendly

I’m not the original poster. I was asking them for more info on their solution.
Thanks for the info, I will try that out :slight_smile:

Hi @PRJ_Soren_Games

Thanks for this info! I am also trying to smooth out analogue input values, but haven’t got it working yet.
I’m prototyping it in blueprint at the moment. In the attached image, I’m using the previous frame input values, and have also tried sampling input values at specific time intervals, but not getting any smoothing. What kind of weight values are you using, and what value are you using as the “Previous Sample” in the WeightedMovingAverage function? Please let me know what I’m missing in the image attached or if you have some more specific example code?

Thanks so much :)!

It probably is indeed, however you can tune the acceleration from your Character Movement component; by default it’s set to give that instant-acceleration feeling. Drastically lower it and you’ll see a significant change.