Rotate camera like VR on mobile
Hi, i'm working on a mobile/vr app that the user can look around in 360. When working in VR I simply activate the built in solution in Unity and everything works fine. The built in VR mode handles perfectly the gyroscope and rotates the camera to the right position on any smartphone I tested that had support.
My problem is that I can't use that rotation outside of VR mode, so I need to make my own implementation for rotating the camera using the gyroscope. I tried using Input.gyro.attitude and it works perfectly on the IOS devices I tested, but on Android devices everything falls apart. On some the gyroscope is glitchy and acting strange, on others the gyroscope is receiving input from acceleration and that is super weird. I moved to Input.gyro.rotationRateUnbiased for the rotation, it is better, but it starts to lose it's orientation after a while and if I shake the device every thing goes crazy and I end up in a random rotation.
Is there a simple solution for this? Why does this happen only on Android devices? Can i get the VR rotation even outside of VR?
If anyone can help me I'd be really grateful.
Answer by ismaelnascimento01 · May 31, 2017 at 05:35 PM
Check link: https://www.youtube.com/watch?v=HIduNSjAQjU and https://docs.unity3d.com/ScriptReference/Input-acceleration.html
thx for the reply. This is not what I want to do. I need de orientation in space of the device, not the acceleration.
Answer by abdulthegamer · Jun 09, 2017 at 03:33 AM
Hi,
If you have already implemented VR mode then just
disable VR in GVR viewer gameobject or prefab and it will handle Gyro automatically. No need to implement again for standard mode.
Or Just Disable like below if you using Google VR package.
GvrViewer.Instance.VRModeEnabled = false;
Answer by HanSoloYolo · Jul 23, 2017 at 09:52 PM
Thank you for your answers, but I believe you are misunderstanding the question.
This is the code you need to have VR without a Headset. Now, I am trying to figure out how to have 2 finger touches reset the camera to it's original orientation offset from the phones current orientation. So if you were lying down and aiming the phone up, you can tap 2 fingers and set the view to your current gyro.attitude. How would you modify the below to do so?
Create an Empty Game Object and name it "Gyro Control". You can rename it, but you would also have to do so in the code following.
Drag Main Camera onto Gyro Control. Now the Gyro Control is the parent object.
Right-Click on your Assests folder in Project View and select Create > C# Script. Name it GyroController.
Erase everything and cut & paste the following code:
"using UnityEngine; public class GyroController : MonoBehaviour { private bool gyroEnabled; private Gyroscope gyro; private GameObject GyroControl; private Quaternion rot;" +
private void Start ()
{
GyroControl = new GameObject ("Gyro Control");
GyroControl.transform.position = transform.position;
transform.SetParent (GyroControl.transform);
gyroEnabled = EnableGyro();
}
private bool EnableGyro()
{
if (SystemInfo.supportsGyroscope)
{
gyro = Input.gyro;
gyro.enabled = true;
GyroControl.transform.rotation = Quaternion.Euler(90f, -90f, 0f);
rot = new Quaternion(0, 0, 1, 0);
return true;
}
return false;
}
private void Update ()
{
if (gyroEnabled)
{
transform.localRotation = gyro.attitude * rot;
}
}
}
Now... how to get it where if (Input.touchCount == 2) the scene recenters on your current gyro.attitude?
It has something to do with Quaternion.identity
, rot, gyro.attitude
, if (Input.touchCount == 2) {transform.localRotation = Quaternion.identity * gyro.attitude}
, or who knows?
This way you can recalibrate the game to whatever angle you are currently facing.
So, I hired a tutor and figured it out. The following works!
using UnityEngine;
public class GyroController2 : $$anonymous$$onoBehaviour
{
private bool gyroEnabled;
private Gyroscope gyro;
private GameObject GyroControl;
private Quaternion rot;
private Quaternion adjustrot;
private void Start ()
{
GyroControl = new GameObject ("Gyro Control");
GyroControl.transform.position = transform.position;
transform.SetParent (GyroControl.transform);
gyroEnabled = EnableGyro();
adjustrot = Quaternion.Euler(90f, 0f, 0f) * Quaternion.Inverse (gyro.attitude);
}
private bool EnableGyro()
{
if (SystemInfo.supportsGyroscope)
{
gyro = Input.gyro;
gyro.enabled = true;
GyroControl.transform.rotation = Quaternion.Euler(90f, -90f, 0f);
rot = new Quaternion(0, 0, 1, 0);
return true;
}
return false;
}
private void Update ()
{
if (gyroEnabled)
{
if (Input.touchCount == 3)
{
adjustrot = Quaternion.Euler(90f, 0f, 0f) * Quaternion.Inverse (gyro.attitude);
}
transform.localRotation = adjustrot * gyro.attitude * rot;
}
}
}