Simple iPhone Calibration

Quaternion

For Moonbase: Lander I needed a way to calibrate the starting or neutral position of the device in a manner that could be stored and re-used during game play.

I looked on the Unity3D forums, and found this thread:

http://forum.unity3d.com/viewtopic.php?t=15684

… where Sandoze, from Fuel Games posted their solution.

 

I converted this from C# to Unity.js, and later modified it with the help of Neil Carter (NCarter) on the #unity3d irc channel.

And this is what I finally came up with:

This is the function to call when calibrating the device, and the variable to store the information:

private var calibrationQuaternion : Quaternion;

//Used to calibrate the iPhoneIput.acceleration input
function CalibrateAccelerometer () {
    var accelerationSnapshot : Vector3 = iPhoneInput.acceleration;
    var rotateQuaternion : Quaternion = 
      Quaternion.FromToRotation (new Vector3 (0.0, 0.0, -1.0), accelerationSnapshot);
    calibrationQuaternion = Quaternion.Inverse (rotateQuaternion);
}

This is the function to call when calibrating the iPhone input:
//Get the 'calibrated' value from the iPhone Input
function FixAcceleration (acceleration : Vector3) {
    var fixedAcceleration : Vector3 = calibrationQuaternion * acceleration;
    return fixedAcceleration;
}

This is a subsection of code to illustrate how it’s used:
//    A sub-section of code from function Update()
function Update()
    //    Some code...
    var acceleration : Vector3 = iPhoneInput.acceleration;
    var fixedAcceleration : Vector3 = FixAcceleration (acceleration);
    var rawTurn : float = (turnReversed) ? -(acceleration.x) : acceleration.x;
    var rawThrust : float = (thrustReversed) ? -(fixedAcceleration.y) : fixedAcceleration.y;
    //    Some more code...
}

Store the var calibrationQuaternion : Quaternion so it can be used by the game. I do not store this to PlayerPrefs, but require the player to recalibrate the device at the beginning of every play session. To store a quaternion to PlayerPrefs, you’d need to reduce it to basic data and then reassemble it upon the start of a new game.

What is missing from this example, which I have seen in others, is a way to take input over a short period of time and smooth it into an average to diminish the effects of instability or shakes by the player.I found that this smoothing was a minimal improvement to the value of the calibration, and this example was far simpler code. For more information on smoothing accelerometer input, see the Unity documentation.

I include a “calibrate” button in my pause menu, so the player can recalibrate at any time. I found this useful when changing positions or swapping hands.

This code was extricated from a larger project. Please let me know if there is something unclear or missing.

 

– Little Angel

No Comments

Leave a Comment

Please be polite. We appreciate that. Your email address will not be published and the required fields are marked.