I am adding tilt controls to my game. The sensor values I get are different in different android devices which results in random behavior.

Anyone knows how can I tackle this situation?

I tried normalizing acceleration but it is still the same.

  • 1
    \$\begingroup\$ You could provide a calibration utility. \$\endgroup\$ – jgallant Mar 31 '16 at 10:56
  • \$\begingroup\$ Hmm will look into it...will that provide contsant acelration value in all device? In my Xiomi Redmi 1s it's giving me max tilt value of 0.4 whereas in Xiaomi Mi 4 it's goes till 0.9 as max value \$\endgroup\$ – idurvesh Mar 31 '16 at 11:20
  • 1
    \$\begingroup\$ The trick is to get the user to tilt their device to get an idea of the range. You can then set your values. I have never done this myself, however, this seems to be the way other developers handle tilt controls. I am hoping someone chimes in with an answer on this one for you. \$\endgroup\$ – jgallant Mar 31 '16 at 11:22
  • \$\begingroup\$ I tried calibration ,but I think its more to do with Low pass filter than to angle at which user is holding device.... \$\endgroup\$ – idurvesh Mar 31 '16 at 12:51

I think Jons correct. I don't know what you mean about low pass filter.

One way is to deal in local range values for your game. Like a range of 0-1. 0 is no tilt, 1 is max tilt. Your game always expects 0-1. Then your calibration create values to convert the device values into your to your local range.

So for example, your redmi extent is 0.4.

1.0 / 0.4 == 2.5. You then multiply your redmi device values by 2.5 to get the 0 -> 1 range.

for your Mi 1.0 / 0.9 == 1.11. You then multiply your Mi device values by 1.11 to get the 0 -> 1 range.


I use this and it seems to work on different devices. The motion of putting the phone down gives me a value for the delta x of -0.5041921 on a samsung galaxy and a -0.5021868 on a Nexus 5.

using UnityEngine;
using UnityEngine.UI;
public class GyroController : MonoBehaviour {
 //   public Text x, y, z;
    public Dice dice;
    public GameManager gameManger;
    public float lowPassKernelWidhtInSeconds;
    private float acceleromerUpdateInterval;
    private float lowPAssFilterFactor;
    private Vector3 lowPassValue;

    private Vector3 phoneAcc, phoneDeltaAcc;
    // Use this for initialization
    void Start () {
        Input.gyro.enabled = true;
        acceleromerUpdateInterval = 1.0f / 60.0f;
        lowPAssFilterFactor = acceleromerUpdateInterval / lowPassKernelWidhtInSeconds;
        lowPassValue = Vector3.zero;

    // Update is called once per frame
    void Update () {
       //x.text ="X: " + Input.gyro.userAcceleration.x;
       //y.text ="Y: " + Input.gyro.userAcceleration.y;
       //z.text ="Z: " + Input.gyro.userAcceleration.z;
    void FixedUpdate()
        phoneAcc = Input.acceleration;
        phoneDeltaAcc = phoneAcc - LowPassFilter(phoneAcc);


    private Vector3 LowPassFilter( Vector3 newSample)
        lowPassValue = Vector3.Lerp(lowPassValue, newSample, lowPAssFilterFactor);
        return lowPassValue;


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.