I can’t seem to get the Gyroscope to control the camera correctly in Android. I’m trying to build a game that uses a mobile device held horizontally as a view port into the game world. Where the top of the device would be pointing to the left and the bottom of the device would be pointing to the right. Then rotating the device will cause the camera to follow the rotation. I’m getting varied results depending on which real world direction I’m facing when I start the game. If I’m facing South the results are perfect, exactly what I want. However, if I’m facing North rotating Left rotates the camera Right, and rotating Right rotates the camera Left. As you can imagine everything in between is kind of meh… Please see my code below and let me know if there is anything I can update to make the Camera follow the device rotation correctly regardless of what real world direction the user is facing. Also, some info on my setup. I’ve got a Player object which is stationary for the most part, but I have a script to rotate the player back to facing the +Z axis after considering the initial gyroscope rotation.
public class RotatePlayer : MonoBehaviour {
private float gyroTimeout = 0f;
private GyroCamera gyroCam;
// Use this for initialization
void Start () {
gyroCam = Camera.main.GetComponent<GyroCamera> ();
StartCoroutine ("GetTheYCalibration");
}
public void RotatePlayerYAxis()
{
float yAngle = gyroCam.GetYAngle ();
/* think of this as rotating the camera base */
this.transform.Rotate (new Vector3 (0f, 0f, yAngle));
}
IEnumerator GetTheYCalibration()
{
// provide some time for gyro initialization
while (gyroTimeout > -30) {
gyroTimeout -= Time.realtimeSinceStartup;
yield return null;
}
RotatePlayerYAxis ();
}
}
The camera is a child of the Player object and uses the below script to control the Camera’s rotation.
public class GyroCamera : MonoBehaviour
{
private float initialYAngle = 0f;
private Gyroscope gyro;
private Quaternion gyroAttitude;
private bool gyroSupport;
private bool gyroEnabled;
// sensitivity vars
public float speed = 4.0f;
public float sensitivity = 0.8f;
void Start()
{
gyroSupport = SystemInfo.supportsGyroscope;
if (gyroSupport) {
gyro = Input.gyro;
gyroEnabled = true;
gyro.enabled = true;
} else {
gyroEnabled = false;
print ("NO GYRO");
}
ApplyCalibration ();
}
void Update()
{
if (gyroEnabled) {
ApplyGyroRotation ();
}
}
void ApplyGyroRotation()
{
Quaternion newRotation = Quaternion.Slerp(gyroAttitude,
Input.gyro.attitude,
Time.deltaTime * speed * sensitivity);
transform.localRotation = newRotation;
transform.Rotate( 30f, 0f, 180f, Space.Self ); // Swap "handedness" of quaternion from gyro.
transform.Rotate( 90f, 180f, 0f, Space.World ); // Rotate to make sense as a camera pointing out the back of your device.
// save the current gyro rotation for the next update
gyroAttitude = newRotation;
}
void ApplyCalibration()
{
transform.localRotation = Input.gyro.attitude;
transform.Rotate( 30f, 0f, 180f, Space.Self ); // Swap "handedness" of quaternion from gyro.
transform.Rotate( 90f, 180f, 0f, Space.World ); // Rotate to make sense as a camera pointing out the back of your device.
initialYAngle = transform.eulerAngles.y; // Save the angle around y axis in order to rotate the player accordingly
}
/* Used to get the original Y Angle in order to rotate the player
* in the positive Z direction regardless of which direction the user
* was facing when they started playing
*/
public float GetYAngle() {
ApplyCalibration ();
return initialYAngle;
}
}
Any assistance is greatly appreciated as I’ve been struggling to fix this issue for quite some time.
Thanks!