It's still a non solved issue, as explained in this post:
GvrViewerMain rotates the camera yourself. Unity3D + Google VR
But according to your needs, you may find usefull the following workaround.
The idea is to find the delta rotation and ignore it if too small.
using UnityEngine;
public class GyroCorrector {
public enum Correction
{
NONE,
BEST
}
private Correction m_correction;
public GyroCorrector(Correction a_correction)
{
m_correction = a_correction;
}
private void CorrectValueByThreshold(ref Vector3 a_vDeltaRotation, float a_fXThreshold = 1e-1f, float a_fYThreshold = 1e-2f, float a_fZThreshold = 0.0f)
{
// Debug.Log(a_quatDelta.x + " " + a_quatDelta.y + " " + a_quatDelta.z );
a_vDeltaRotation.x = Mathf.Abs(a_vDeltaRotation.x) < a_fXThreshold ? 0.0f : a_vDeltaRotation.x + a_fXThreshold;
a_vDeltaRotation.y = Mathf.Abs(a_vDeltaRotation.y) < a_fYThreshold ? 0.0f : a_vDeltaRotation.y + a_fYThreshold;
a_vDeltaRotation.z = Mathf.Abs(a_vDeltaRotation.z) < a_fZThreshold ? 0.0f : 0.0f;//We just ignore the z rotation
}
public Vector3 Reset()
{
return m_v3Init;
}
public Vector3 Get(Vector3 a_v3Init)
{
if (!m_bInit)
{
m_bInit = true;
m_v3Init = a_v3Init;
}
Vector3 v = Input.gyro.rotationRateUnbiased;
if (m_correction == Correction.NONE)
return a_v3Init + v;
CorrectValueByThreshold(ref v);
return a_v3Init - v;
}
}
... And then use something like this in the "UpdateHead" method from "GvrHead":
GvrViewer.Instance.UpdateState();
if (trackRotation)
{
var rot = Input.gyro.attitude;//GvrViewer.Instance.HeadPose.Orientation;
if(Input.GetMouseButtonDown(0))
{
transform.eulerAngles = m_gyroCorrector.Reset();
}
else
{
transform.eulerAngles = m_gyroCorrector.Get(transform.eulerAngles);//where m_gyroCorrector is an instance of the previous class
}
}
You may find some problems. Mainly but not exclusive:
There will be a latence problem when moving the head as there is an offset to detect the movement
You are dealing with relative positions that come with imprecisions. So you are not 100% sure to find the same position
when doing the opposite movement.
You are using euler representation instead of quaternion, and it seems to be less accurate.
You may also be interested in these links speaking about the field:
http://scholarworks.uvm.edu/cgi/viewcontent.cgi?article=1449&context=graddis
Gyroscope drift on mobile phones
and this piece of code :
https://github.com/asus4/UnityIMU
Hope it can help,