How to set viewpoint regardless of tilt of device when use gyroscope
I succeeded in using the gyroscope to allow the camera viewpoint to change the angle according to the tilt of the device.
But what I want to do is, let camera see where I want to regardless of device tilt when the game starts.
I have already tried one but failed.
A) Quaternion value of the device
B) Quaternion value of the device when game scene starts
C) difference in Euler Angle between A and B
D) Quaternion value of main camera looking at where I want to be
I assigned a quaternion of D plus C to the angle of the camera.
Test results were smooth, but when device had a certain angle, the view of the camera rotated to an unusual angle.
I find it seems to be a problem caused by Gimbal Lock and I have not found a way to solve it.
Here is my code.
Look Update
private bool gyroEnabled;
private Gyroscope gyro;
private GameObject cameraContainer;
public Quaternion rot;
public Quaternion finalQuaternion;
public float finalEulerX = 0;
public float finalEulerY = 0;
public float finalEulerZ = 0;
public Quaternion quaternion;
public float QuaternionToEulerX = 0f;
public float QuaternionToEulerY = 0f;
public float QuaternionToEulerZ = 0f;
public bool initialQuaternionCheck = false;
public Quaternion initialQuaternion;
public float initialQuaternionToEulerX = 0f;
public float initialQuaternionToEulerY = 0f;
public float initialQuaternionToEulerZ = 0f;
public float alteredEulerX = 0f;
public float alteredEulerY = 0f;
public float alteredEulerZ = 0f;
public bool initialLookAtQuaternionCheck = false;
public Quaternion lookAtQuaternion;
public float lookAtQuaternionToEulerX = 0f;
public float lookAtQuaternionToEulerY = 0f;
public float lookAtQuaternionToEulerZ = 0f;
void Start() {
cameraContainer = new GameObject("Cameara Container");
cameraContainer.transform.position = transform.position;
transform.SetParent(cameraContainer.transform);
gyroEnabled = EnableGyro();
}
private bool EnableGyro()
{
if (SystemInfo.supportsGyroscope)
{
gyro = Input.gyro;
gyro.enabled = true;
cameraContainer.transform.rotation = Quaternion.Euler(90f, 90f, 0f);
rot = new Quaternion(0, 0, 1, 0);
return true;
}
return false;
}
private void SetInitialQuaternion()
{
initialQuaternionCheck = true;
initialQuaternion = quaternion;
initialQuaternionToEulerX = initialQuaternion.eulerAngles.x;
initialQuaternionToEulerY = initialQuaternion.eulerAngles.y;
initialQuaternionToEulerZ = initialQuaternion.eulerAngles.z;
}
private void SetInitialLookAtQuaternion()
{
initialLookAtQuaternionCheck = true;
transform.LookAt(focus.transform);
lookAtQuaternion = transform.localRotation;
lookAtQuaternionToEulerX = lookAtQuaternion.eulerAngles.x;
lookAtQuaternionToEulerY = lookAtQuaternion.eulerAngles.y;
lookAtQuaternionToEulerZ = lookAtQuaternion.eulerAngles.z;
}
private void CheckAlteredQuaternion()
{
alteredEulerX = QuaternionToEulerX - initialQuaternionToEulerX;
alteredEulerY = QuaternionToEulerY - initialQuaternionToEulerY;
alteredEulerZ = QuaternionToEulerZ - initialQuaternionToEulerZ;
}
void Update()
{
if (gyroEnabled)
{
quaternion = gyro.attitude * rot; // A) Quaternion value of the device
QuaternionToEulerX = quaternion.eulerAngles.x;
QuaternionToEulerY = quaternion.eulerAngles.y;
QuaternionToEulerZ = quaternion.eulerAngles.z;
if (initialQuaternionCheck == false)
{
SetInitialQuaternion(); // B) Quaternion value of the device when game scene starts
}
CheckAlteredQuaternion(); // C) difference in Euler Angle between A and B
if (initialLookAtQuaternionCheck == false)
{
SetInitialLookAtQuaternion(); // D) Quaternion value of main camera looking at where I want to be
}
Vector3 result = lookAtQuaternion.eulerAngles - new Vector3(alteredEulerX, alteredEulerY, alteredEulerZ);
finalQuaternion = Quaternion.Euler(result);
transform.localRotation = finalQuaternion;
}
}
Do i miss something?
or Wrong approach?
If not, how can I change my camera angle freely from the Gimbal Lock?