0
\$\begingroup\$

I am working on a project where I want to create an 'scrolling' effect using gyroscope on mobile devices. The basic idea is that I have an Image object in my Scene and I want to be able to show different part of it using gyroscope like for example you see the wall of a room and rotation your phone you see different parts of the room, but in 2D.

For now I managed to move my Image using Input.gyro.attitude.eulerAngles.x; from gyroscope like this:

    protected void Update()
    {
        var x = transform.localPosition.x;
        var gyroX = Input.gyro.attitude.eulerAngles.x;
        x += -gyroX * Speed;

        BackgroundImage.transform.localPosition =
            new Vector3(x, transform.localPosition.y, transform.localPosition.z);

    }

The problem which I am seeing is that when Input.gyro.attitude.eulerAngles.x reaches 86.0 it starts decreasing and even if you are rotating your phone to right it changes it's direction.

Checked the documentation, examples over internet, but didn't find anything about that.

If you have any idea what can cause that issue and how can I fix it, or any other suggestions how can I achieve the thing which I want to create, pleae share your knowledge.

Thanks in advance!

Edit: The only rotation axis which I am interested in is X, because the app will be in portrait mode and I want to be able to move the image only horizontal (by X).

So the phone's rotation has to be similar to while taking an panoramic photo on your mobile as shown on the first picture:

enter image description here

\$\endgroup\$
  • \$\begingroup\$ You probably don't want to use Euler angles for this. They're good for specifying one complete orientation to be used as-is. They're not good for decomposing that orientation into component parts (each component can change meaning depending on the values of the other components) or for dynamically modifying/comparing orientations. Can you phrase your desired control scheme in terms of direction vectors, perchance? These behave in a more uniform & intuitive manner. \$\endgroup\$ – DMGregory Oct 2 '17 at 12:58
  • \$\begingroup\$ @DMGregory the idea which I am trying to achieve is that: 1. The main background image is centered and when I rotate my phone to left, the image should move according to the angle of rotation so the user can see the left part of the image. 2. If I rotate the phone to right, the idea is the same as above. Most of the stuff which I see over internet are for rotating the object, but since I am working on 2D, rotating the image is not an option, it has to move by X. \$\endgroup\$ – hardartcore Oct 2 '17 at 15:54
  • \$\begingroup\$ Try including a diagram in your question. Rotational movement plus different phone-holding orientations makes it easy for ambiguity to creep in. \$\endgroup\$ – DMGregory Oct 2 '17 at 16:10
  • \$\begingroup\$ Just edited the question, with a little bit more info about the thing which I want to achieve. \$\endgroup\$ – hardartcore Oct 2 '17 at 16:33
0
\$\begingroup\$

To pan your image based on the relative rotation of your phone, you'll want to use Gyroscope.rotationRateUnbiased instead of Gyroscope.attitude. The latter describes the current orientation of the phone, which means it will wrap around when you rotate your phone a full 360 degrees, and your magnitude depends on how far you are from Unity's global zero, not how fast you're turning your phone.

In contrast, rotationRateUnbiased gives the instantaneous speed of rotation about each axis, which sounds more like what you're looking for. Remember to scale the speed by deltaTime so your movement doesn't jump/stutter or show inconsistencies under framerate changes.

protected void Update()
{
    var x = transform.localPosition.x;

    // I'm assuming the x axis of the phone is the one crossing the phone's
    // long axis - the Unity docs are a bit coy about important details like this....
    var gyro = Input.gyro.rotationRateUnbiased.x * Time.deltaTime;

    x -= gyro * Speed;
    // You may want to clamp or wrap x here in your image space.

    BackgroundImage.transform.localPosition =
        new Vector3(x, transform.localPosition.y, transform.localPosition.z);
}
\$\endgroup\$
  • \$\begingroup\$ tried that, but the image is moving with a few pixels. checked the value which returns Input.gyro.rotationRateUnbiased.x, it's something like 0,0032242 / 0.0012323 ... I've used attitude, because it's the only object which gives me rotation angles as 0 / 360, but there is an issue as I described with decresing the value after reaching 86 degree. \$\endgroup\$ – hardartcore Oct 3 '17 at 12:54
  • \$\begingroup\$ So after var gyro = Input.gyro.rotationRateUnbiased.x * Time.deltaTime; x -= (gyro * Mathf.Rad2Deg) * Speed; (btw Speed = 5f) , still has almost the same result, with a little bit more movement. \$\endgroup\$ – hardartcore Oct 3 '17 at 13:05
  • \$\begingroup\$ Then make Speed much much much bigger. \$\endgroup\$ – DMGregory Oct 3 '17 at 13:06
  • \$\begingroup\$ still lot more glitchy and not so accurate in my opinion..using Gyroscope.attitude was giving better results, but with the issue. \$\endgroup\$ – hardartcore Oct 3 '17 at 13:13
  • \$\begingroup\$ Then describe the glitches. We can't fix a problem without knowing what it is. \$\endgroup\$ – DMGregory Oct 3 '17 at 13:28

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.