Gravtiy/Tilt motion on Android device is twitching and very sensitive, is there a way to smooth this out?

Hello,

Basically I have just started using UE4 and getting use to this amazing blueprint stuff. I’m testing out camera controls by the orientation of an android mobile device to look around a 3d enviroment or to change the rotation of an object by at least 180 degrees on each axis. It sort of works but as you hold the device the camera movement is very sensitive with a random twitching glitch.

I have tried methods from older answers and have so far come up with this current blueprint below:

It tries to reduce sensitivity but it is also restricting movement. The crazy twitching is probably caused by this blueprint so i know I made a mistake somewhere.

Any way to do this better?

Thanks,

Regards

Couldn’t you just use the axis value of the Rotation Rate rate event directly?

87706-screen+shot+2016-04-20+at+12.34.34+pm.png

I just tried that directly to the SetWorldRotation function and its behavior is totally erratic and not controllable.

Also tried it with the rest of the blueprint, connecting it from the ‘Break Vector’ part and it was barely responsive.

Yes before posting this question I have tried all of these motion events, each with their own odd quirks. So far, I get better results from using the gravity sensor, but not without the current problems.

Maybe you’ll have better luck with the other motion events?

87710-screen+shot+2016-04-20+at+1.30.25+pm.png

Well I tried everything I could think of, so I have to assume it’s a bug with motion events for Android devices.

Yes. You can make it smooth.

After over a year of improving the results myself over the course of the project, but never quite solving the twitchy problem, a new advisor to our company, who is an expert gameplay engineer, came up with an elegant and perfectly effective dampening algorithm. It really works.

I’ve experienced a lot of heartache with tilt on mobile, trying to make it to actually be smooth, and I’ve seen many others here that have tried and failed as well… so here is the real, actual solution:

This fires off every frame. You can either power it with Tick, or with a looped Timeline. I recommend using a looped Timeline, so you can turn it off/on at will. Tick in Blueprints seems to impact performance more than Timelines, at least as far as my testing has revealed.

Here’s what’s happening:

  1. Mobile Tilt Input is being received from the hardware, whether that’s Gravity, Tilt… whatever. It handles a single axis value. Before setting it previous to this algorithm, do whatever multiplication you need to do to expand the range of motion in your game relative to the device’s motion.
  2. Tilt Array contains 5 array elements as default. This algorithm stores previous frames and averages them for a final output. The amount of array elements you have it set to will determine how many previous frames are stored in the array. 5 works just fine, but feel free to play around.
  3. Tilt Array Index is used to change what element in the array the current frame’s value is being stored in.
  4. After setting the array element, increment the array index, and then modulo the resulting index with the length of the array. What this does is reset the index back to 1 if the most recent array element that had a stored value was 4 (5th element), or whatever your max is. If not, it simply lets it increment and moves on.
  5. Last Index of the ForLoop is set to the highest array element, so array length - 1.
  6. Loop body adds up all values of the array.
  7. On completed, divide Tilt by the array length (5, or whatever you want) and output final value.

TL;DR version:
Store previous frames and average them. Make sure Tilt Array has 5 array elements as default, or whatever amount you wanna try. Just do 5 first.

Try it out and be happy.

Wow thanks for your answer, great to know it can actually be done with blueprints. I will try to follow this and pick up where I left off.

Yep it works and I’m happy.

Since I needed 2 axis values to be dampened I got this running for X with another for Y in a Sequence. It appears to work fine, is that an efficient approach to manage it?

Thanks again and send my regards to the expert gameplay engineer.

Aw yis.

That works. But I find that for the sake of good programming principles, copying nodes/code like that usually means there’s a more simple and dynamic solution. You could actually just use a vector rather than a single float for the algorithm input/output. Change the Tilt Array to a vector array, and Tilt to a vector. For setting your Mobile Tilt Input (also now a vector) previous to the algorithm, you’d use a Make Vector and plug in each axis input to the corresponding vector axis.
It’s up to you if you wanna use 1, 2, or all 3 vector axes; one of them being 0 won’t matter as long as you aren’t actually using it later. I set it up with a single float input/output because I’m only using a single axis from Rotation Rate to do my thang.

Will do!

I was implementing exactly the same solution as described by DG Gage
but an “average” by definition is always affected by the extremes of the data
that means that if at any moment you get an erratic value your whole array “history”
is affected for example 1,2,2,30,1 then you get a bad movement until the history
removes the “30”.
There is fashion/mode (maybe i am translating bad, my native language is spanish)
wich gives you the most repeated value from your data so i implemented it and got
nice results by combining it with average