Get Accelerometer to rotate 360 degrees

Hello. I’m using the accelerometer to rotate an object in a game so that the object always points upwards (away from the centre of the Earth let’s say) no matter what way the phone is rotated around the z-axis. Think of it like a compass the way the needle always points north no matter what way you have the device rotated. I’m coding in C#.

using UnityEngine;
using System.Collections;

public class RotateDial : MonoBehaviour {
	private Quaternion localRotation; 
	void Start () {
		// copy the rotation of the object itself into a buffer
            localRotation = transform.rotation;
	void Update () {
		localRotation.z = Input.acceleration.x; 
            transform.rotation = localRotation;
	void OnGUI() {
		GUI.Box (new Rect (5, 55, Screen.width / 2, 20), "Local z" + localRotation.z); //, Health_bar_GUI);
		GUI.Box (new Rect (5, 80, Screen.width / 2, 20), "Accel x" + Input.acceleration.x); //, Health_bar_GUI);
		GUI.Box (new Rect (5, 105, Screen.width / 2, 20), "transform rot" + transform.rotation); //, Health_bar_GUI);

My problem is that the accelerometer only seems to work across 180 degrees. The rotation translation for the particular axis is 0 when the phone is held in landscape mode but is either -1 or +1 when it’s held portrait (+90 degrees) or upside down portrait (270 or -90 degrees) which works correctly for these rotations. When the phone is held beyond 90 but below 270 degrees the game object does not point in the correct direction. I’ve attached an image to help explain the problem a bit better.


I believe it to be because the rotation translation goes back to 0 when the phone is held in upside down landscape mode (180 degrees).

Does anyone know a solution that will allow the game object to keep pointing in the same direction even if the phone is turned completely upside down? Thanks in advance.

You have to use at least the X and Y axis to calculate the rotation. Remember, you are reading gravity force per axis. If you turn your device clockwise, the value on the X axis will raise until 1.0 at 90 degree but then start falling again between 90 and 180 degree. At the same time the value for the Y axis change from negative to positive between 0 and 180 degree.

Starting with landscape mode and rotating around the Z axis, the X,Y values will be:

  • 0° = (0, -1)
  • 90° = (1, 0)
  • 180° = (0, 1)
  • 270° = (-1, 0)

My guess is that your acceleration shows the right direction, but the phone changes Input.deviceOrientation, so you get turned around again.

Write out the Angle and the deviceOrientation to a label. If I’m right, add 180 to the angle if the deviceOrientation is on the head.