# Smartphone tilt calculation when using gyroscope in Unity (smartphone moving problem)

I have been trying for several days now to set up the correct behavior of the gyroscope in Unity. I want to make it so that when the smartphone is tilted, the object tilts along the z-axis. I found several variants of the code on the Internet and I managed to correctly calculate the slope and block the change in rotation when the smartphone is tilted forward or backward. But one problem remains, in which, if you pick up a smartphone and turn around its axis, the angle of rotation of the object also changes. As I understand it, this is due to the fact that in addition to the tilt, the gyroscope also calculates the change in the rotation of the smartphone in space. Here is my code:

public class TestInputController : MonoBehavior
{
public Transformbg;
private Quaternion referenceRotation;

void Start()
{
input.gyro.enabled = true;
referenceRotation = GetDeviceRotation();
}

private Quaternion GetDeviceRotation()
{
return new Quaternion(0.5f, 0.5f, -0.5f, 0.5f) * Input.gyro.attitude * new Quaternion(0, 0, 1, 0);
}

private float GetRollAngle(Quaternion refRotation, Quaternion currentRotation)
{
Quaternion eliminationOfXY = Quaternion.Inverse(Quaternion.FromToRotation(refRotation *
Vector3.forward, currentRotation * Vector3.forward));

Quaternion rotationZ = eliminationOfXY * currentRotation;
return rotationZ.eulerAngles.z;
}

void Update()
{
bg.transform.rotation = Quaternion.Slerp(bg.transform.rotation,
Quaternion.Euler(0f, 0f, GetRollAngle(referenceRotation, GetDeviceRotation())),
8f * Time.deltaTime);
}
}


How can you remove the dependence on the rotation of the smartphone in space and leave only the calculation of the angle of inclination to rotate the object along the z axis?

Quaternions must have a vector length of one, so Quaternion(0.5f, 0.5f, -0.5f, 0.5f) is an invalid Quaternion.

Your post multiply new Quaternion(0, 0, 1, 0)' rotates 180 degrees about the Y axis.

Yes, Quaternion math is weird, but unless you fully understand the restrictions:

Since gimbol lock cannot affect a single angle:

private Quaternion GetDeviceRotation()
{
return Quaternion.FromEuler(0,0,Input.gyro.attitude.eulerAngles.Z);//move to needed axis
}
`

Never be afraid to go back to simple Euler angles. Just don't try to rotate them.