Aligning Gyro or World with Compass

Hello!

I’ve been trying to snap a scene with a gyro camera to the magnetic north, but have been unable to. I’m using the following code: does anyone have a suggestion on how it SHOULD work?

#pragma strict

// Gyroscope-controlled camera for iPhone  Android revised 2.26.12
// Perry Hoberman <hoberman@bway.net>
//
// Usage:
// Attach this script to main camera.
// Note: Unity Remote does not currently support gyroscope.
//
// This script uses three techniques to get the correct orientation out of the gyroscope attitude:
// 1. creates a parent transform (camParent) and rotates it with eulerAngles
// 2. for Android (Samsung Galaxy Nexus) only: remaps gyro.Attitude quaternion values from xyzw to wxyz (quatMap)
// 3. multiplies attitude quaternion by quaternion quatMult
//
// Also creates a grandparent (camGrandparent) which can be rotated with localEulerAngles.y
// This node allows an arbitrary heading to be added to the gyroscope reading
// so that the virtual camera can be facing any direction in the scene, no matter what the phone's heading

static var gyroBool : boolean;
private var gyro : Gyroscope;
private var quatMult : Quaternion;
private var quatMap : Quaternion;

private var camGrandparent : GameObject;
private var setToNorth : boolean = false;

function Awake() 
{

	// find the current parent of the camera's transform
	var currentParent = transform.parent;
	
	// instantiate a new transform
	var camParent = new GameObject ("camParent");

	// match the transform to the camera position
	camParent.transform.position = transform.position;
	
	// make the new transform the parent of the camera transform
	transform.parent = camParent.transform;
	
	// make the original parent the grandparent of the camera transform
    camParent.transform.parent = currentParent;
    
    // instantiate a new transform
    camGrandparent = new GameObject ("camGrandParent");
    
    // match the transform to the camera position
    camGrandparent.transform.position = transform.position;
    
    // make the new transform the parent of the camera transform
    camParent.transform.parent = camGrandparent.transform;
    
    // make the original parent the grandparent of the camera transform
    camGrandparent.transform.parent = currentParent;
    
    
    
    gyroBool = SystemInfo.supportsGyroscope;
    
    if (gyroBool) 
    {
    	gyro = Input.gyro;
    	gyro.enabled = true;
    	
        #if UNITY_IPHONE
        
        camParent.transform.eulerAngles = Vector3(90,90,0);
        quatMult = Quaternion(0,0,1,0); 
        
        #endif
    } 
    else 
    {
    	print("NO GYRO");
    }
    
    Input.compass.enabled = true;
}

function Update () 
{
	if(Input.compass.magneticHeading != 0  !setToNorth)
	{
		StartCoroutine(SetCompass(1)); 
		setToNorth = true;
	}
	
	
    if (gyroBool) 
    {
    	quatMap = gyro.attitude;
        
        transform.localRotation = quatMap * quatMult;
    }
    
}

function SetCompass(option : int)
{
	//wait to give compass time...
	yield WaitForSeconds (2f);
	//rotate the grand parent to align, or something??
	camGrandparent.transform.localEulerAngles.y = Input.compass.magneticHeading;
	
}

This still gives different results on two devices…

Anyone?

I’ve been noticing something similar - it seems that Input.gyro.attitude always starts at identity from the time the app starts… Is that expected? A little more documentation would go a long way here. :slight_smile:

edit: I just tested with the device tilted - it’s tilt is correct, so the attitude is not necessarily identity as I stated, but seems to be based on the compass heading