[sharing] gyroscope-controlled camera on iPhone 4

Discussion in 'iOS Development' started by phoberman, Aug 1, 2011.

  1. petey

    petey

    Member

    Joined:
    May 20, 2009
    Messages:
    766
    Hye phoberman,

    Thanks heaps for sharing this scene, I would have been pretty stuck trying to figure it out myself. Quaternions are scary!

    I'm trying to expand on it a little though and I was wondering, does anyone know how i could "calibrate" the result on an arbitrary angle? Say if you are on your couch and your device is on a weird angle you could recalibrate it so that angle would be the reset rotation.
    I've tried a few approaches but I'm not really getting anywhere :(

    Any ideas?
    Thanks
    Pete
  2. ilya_ca

    ilya_ca

    Member

    Joined:
    Nov 19, 2011
    Messages:
    216
    Hi,
    How can I roll my camera with this script? I have a camera that's looking to some object and I want to always keep the camera parallel to the floor.

    Thanks!
  3. ina

    ina

    Member

    Joined:
    Nov 15, 2010
    Messages:
    329
    Wow, you had to use the Java call interface - is there really no way to just check for ScreenOrientation in Unity only ?

  4. quitebuttery

    quitebuttery

    Member

    Joined:
    Mar 12, 2011
    Messages:
    192
    No--because Unity compensantes for the natural angle to report if it's Landscape or Portrait. You need to figure out the natural orientation--and the only way to do it is to do it at the Android API level to get the rotation from 'natural'. It's actually a bug in Unity--the Gyro should return the same orientations regardless of how the device is oriented and what platform it's on. I guess they did that for the accelerometer, but forgot to do it for the gyro.
  5. darkmax

    darkmax

    Member

    Joined:
    Feb 21, 2012
    Messages:
    57
    hi, i'm trying to use this for a RA application but, i can't match the virtual north with the real north, any suggestions about this? i tried Input.compass.magneticHeading, but the lecture is to shaky but maybe i need to make a filter for this but i'm not sure if this the correct way of do it, so if any have any ideas i will appreciate.
  6. ina

    ina

    Member

    Joined:
    Nov 15, 2010
    Messages:
    329
    Is this broken for Unity 3.5.6 Android?

  7. quitebuttery

    quitebuttery

    Member

    Joined:
    Mar 12, 2011
    Messages:
    192
    Supposedly the Gyro has been fixed in 3.5.6 so you don't need to flip it anymore based on orientation, or device. I haven't gone back to re-write my gyro camera code but I'm pretty sure none of this works anymore in 3.5.6.
  8. Cascho01

    Cascho01

    Member

    Joined:
    Mar 19, 2010
    Messages:
    423
    Tried on iOS, no changes due to orientation issues although reported as fixed in "What´s new":

    "iOS: Fixed various orientation issues."

    Does anyone get additional rotation of the camera by mouse, as reported in the script, working in vertical direction?
    Horizontal rotation works fine:

    Code (csharp):
    1. // Also creates a grandparent (camGrandparent) which can be rotated with localEulerAngles.y
    2.  
    3. // This node allows an arbitrary heading to be added to the gyroscope reading
    4.  
    5. // so that the virtual camera can be facing any direction in the scene, no matter what the phone's heading
    EDIT: Mouse rotation solved
    Last edited: Oct 12, 2012
  9. kaz2057

    kaz2057

    Member

    Joined:
    Jan 18, 2011
    Messages:
    286
    anybody fixed androdi gyroscope script on 3.5.6? It don't work !!!

    From the changelog:

    Android: Gyro.attitude did not compensate for screen orientation, nor device natural orientation (phone/tablet) - this has been fixed.

    Thanks
  10. kaz2057

    kaz2057

    Member

    Joined:
    Jan 18, 2011
    Messages:
    286
    UP

  11. shinichi88

    shinichi88

    New Member

    Joined:
    May 4, 2011
    Messages:
    71
    "The Unity mobile devices input API is based on Apple's iOS API." (Unity/Editor/Data/Documentation/Documentation/ScriptReference/Input.html)
    Ultimately, I tested this on Unity 3.5.6f4, the setting for Android should be the same as iOS.
    Code (csharp):
    1.  
    2. camParent.transform.eulerAngles = Vector3(90,90,0);
    3.            
    4. if (Screen.orientation == ScreenOrientation.LandscapeLeft) {
    5.    quatMult = Quaternion(0,0,1,0); //**
    6. } else if (Screen.orientation == ScreenOrientation.LandscapeRight) {
    7.    quatMult = Quaternion(0,0,1,0); //**
    8. } else if (Screen.orientation == ScreenOrientation.Portrait) {
    9.    quatMult = Quaternion(0,0,1,0); //**
    10. } else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
    11.    quatMult = Quaternion(0,0,0,1); // Unable to build package on upsidedown
    12. }
    13.  
    Using gyro.Attitude quaternion xyzw
    Code (csharp):
    1.  
    2. quatMap = gyro.attitude;
    3.  
    OR
    Code (csharp):
    **Updates : All Screen Orientation use the same quatMult value.Not sure if this setting apply on iOS
    Code (csharp):
    1.  
    2. quatMult = Quaternion(0,0,1,0);
    3.  
    Personally, I tried this script on Asus Transformer Prime TF201, and Samsung Galaxy Note...
    Both using the same script and work perfectly.
    Last edited: Oct 23, 2012
  12. kaz2057

    kaz2057

    Member

    Joined:
    Jan 18, 2011
    Messages:
    286
    Thanks shinichi88. You are my rescuer!!

    I don't know what was wrong when, last week, I tried to modify the base script with your same value, but i didn't work.

    With your setup now everything works correctly.

    Thanks
  13. shinichi88

    shinichi88

    New Member

    Joined:
    May 4, 2011
    Messages:
    71
    You must be using the old version I've post before the latest update, that come with those 0.707 values. (Current : Quaternion(0,0,1,0) )
    I'm not pretty sure on this settings, but it just work. No idea what's Unity changes from previous with just a few words in changelog.
    Unity should update script reference with example codes in order to get it work correctly.

    There something bothering me about the gyro value. It seems to drift around and it makes the camera "auto rotate" and not precise.
    Not sure which side having problem. Unity API or Hardware?
  14. digiben

    digiben

    New Member

    Joined:
    Aug 18, 2012
    Messages:
    7
    After days and probably over 20 hours of researching and coding and testing to try and find out why the heck I couldn't get the gyroscope to orient correctly, I found this code and it works flawlessly. All the contributors on this are my heros and I am VERY grateful for the time taken to post this code and example.
  15. Voxel85

    Voxel85

    New Member

    Joined:
    Sep 26, 2012
    Messages:
    2
    Can you help me? I use your script in my project. It is a project for my iPhone. It worked perfectly. Since Unity 4, it no longer works. I do not understand the problem. I changed gyroBool = Input.isGyroAvailable; with gyroBool= SystemInfo.supportsGyroscope;. I switched because of this warning:
    WARNING: 'UnityEngine.Input.isGyroAvailable' is obsolete. isGyroAvailable property is deprecated. Please use SystemInfo.supportsGyroscope instead.

    I would be very happy if you could help me.
  16. reganmusic

    reganmusic

    New Member

    Joined:
    Apr 6, 2012
    Messages:
    7
    thanks!!!! you rule!!!!
    Last edited: Dec 11, 2012
  17. Seppel

    Seppel

    New Member

    Joined:
    Jan 7, 2013
    Messages:
    1
    Hello there guys,

    i´m trying to get the gyroscript to work.

    I´m using Unity4pro and an Android Samsung Galaxy S3.
    I´ve changed the Script like shinchi88 already said.
    And now unsing this Script on my MainCamera, but it doesnt work.
    The App is staring but the Camera dont moves by the Gyrodatas.

    Could you please help me?
    Thank You


    Code (csharp):
    1. #pragma strict
    2.     // Gyroscope-controlled camera for iPhone  Android revised 2.26.12
    3.     // Perry Hoberman <hoberman@bway.net>
    4.     //
    5.     // Usage:
    6.     // Attach this script to main camera.
    7.     // Note: Unity Remote does not currently support gyroscope.
    8.     //
    9.     // This script uses three techniques to get the correct orientation out of the gyroscope attitude:
    10.     // 1. creates a parent transform (camParent) and rotates it with eulerAngles
    11.     // 2. for Android (Samsung Galaxy Nexus) only: remaps gyro.Attitude quaternion values from xyzw to wxyz (quatMap)
    12.     // 3. multiplies attitude quaternion by quaternion quatMult
    13.      
    14.     // Also creates a grandparent (camGrandparent) which can be rotated with localEulerAngles.y
    15.     // This node allows an arbitrary heading to be added to the gyroscope reading
    16.     // so that the virtual camera can be facing any direction in the scene, no matter what the phone's heading
    17.      
    18.     static var gyroBool : boolean;
    19.     private var gyro : Gyroscope;
    20.     private var quatMult : Quaternion;
    21.     private var quatMap : Quaternion;
    22.      
    23.     function Awake() {
    24.         // find the current parent of the camera's transform
    25.         var currentParent = transform.parent;
    26.         // instantiate a new transform
    27.         var camParent = new GameObject ("camParent");
    28.         // match the transform to the camera position
    29.         camParent.transform.position = transform.position;
    30.         // make the new transform the parent of the camera transform
    31.         transform.parent = camParent.transform;
    32.         // make the original parent the grandparent of the camera transform
    33.         //camParent.transform.parent = currentParent;
    34.         // instantiate a new transform
    35.         var camGrandparent = new GameObject ("camGrandParent");
    36.         // match the transform to the camera position
    37.         camGrandparent.transform.position = transform.position;
    38.         // make the new transform the parent of the camera transform
    39.         camParent.transform.parent = camGrandparent.transform;
    40.         // make the original parent the grandparent of the camera transform
    41.         camGrandparent.transform.parent = currentParent;
    42.            
    43.         // check whether device supports gyroscope
    44.         #if UNITY_3_4
    45.         gyroBool = Input.isGyroAvailable;
    46.         #endif
    47.         #if UNITY_3_5
    48.         gyroBool = SystemInfo.supportsGyroscope;
    49.         #endif
    50.        
    51.         if (gyroBool) {
    52.             gyro = Input.gyro;
    53.             gyro.enabled = true;
    54.             #if UNITY_IPHONE
    55.                     camParent.transform.eulerAngles = Vector3(90,90,0);
    56.                
    57.                         if (Screen.orientation == ScreenOrientation.LandscapeLeft) {
    58.                            quatMult = Quaternion(0,0,1,0); //**
    59.                         } else if (Screen.orientation == ScreenOrientation.LandscapeRight) {
    60.                            quatMult = Quaternion(0,0,1,0); //**
    61.                         } else if (Screen.orientation == ScreenOrientation.Portrait) {
    62.                            quatMult = Quaternion(0,0,1,0); //**
    63.                         } else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
    64.                            quatMult = Quaternion(0,0,1,0); // Unable to build package on upsidedown
    65.                         }
    66.             #endif
    67.             #if UNITY_ANDROID
    68.                     camParent.transform.eulerAngles = Vector3(90,90,0);
    69.                
    70.                         if (Screen.orientation == ScreenOrientation.LandscapeLeft) {
    71.                            quatMult = Quaternion(0,0,1,0); //**
    72.                         } else if (Screen.orientation == ScreenOrientation.LandscapeRight) {
    73.                            quatMult = Quaternion(0,0,1,0); //**
    74.                         } else if (Screen.orientation == ScreenOrientation.Portrait) {
    75.                            quatMult = Quaternion(0,0,1,0); //**
    76.                         } else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
    77.                            quatMult = Quaternion(0,0,1,0); // Unable to build package on upsidedown
    78.                         }
    79.             #endif
    80.             Screen.sleepTimeout = SleepTimeout.NeverSleep;
    81.         } else {
    82.             #if UNITY_EDITOR
    83.                 //print("NO GYRO");
    84.             #endif
    85.         }
    86.     }
    87.      
    88.     function Update () {
    89.         if (gyroBool) {
    90.             #if UNITY_IPHONE
    91.                 quatMap = gyro.attitude;
    92.             #endif
    93.             #if UNITY_ANDROID
    94.                 quatMap = Quaternion(gyro.attitude.x,gyro.attitude.y,gyro.attitude.z,gyro.attitude.w);
    95.             #endif
    96.             transform.localRotation = quatMap * quatMult;
    97.         }
    98.     }
    Last edited: Jan 7, 2013
  18. ina

    ina

    Member

    Joined:
    Nov 15, 2010
    Messages:
    329
    what's the updated quatMult for Unity 3.5.7?
  19. Wiggitamoo

    Wiggitamoo

    New Member

    Joined:
    Jan 16, 2013
    Messages:
    1
    Really nice work. Worked like a charm!
  20. charmandermon

    charmandermon

    Member

    Joined:
    Dec 4, 2011
    Messages:
    150
    Ive updated the code so it works with Unity 4 :)

    Code (csharp):
    1. #pragma strict
    2.  
    3.     // Gyroscope-controlled camera for iPhone  Android revised 2.26.12
    4.  
    5.     // Perry Hoberman <hoberman@bway.net>
    6.  
    7.     //
    8.  
    9.     // Usage:
    10.  
    11.     // Attach this script to main camera.
    12.  
    13.     // Note: Unity Remote does not currently support gyroscope.
    14.  
    15.     //
    16.  
    17.     // This script uses three techniques to get the correct orientation out of the gyroscope attitude:
    18.  
    19.     // 1. creates a parent transform (camParent) and rotates it with eulerAngles
    20.  
    21.     // 2. for Android (Samsung Galaxy Nexus) only: remaps gyro.Attitude quaternion values from xyzw to wxyz (quatMap)
    22.  
    23.     // 3. multiplies attitude quaternion by quaternion quatMult
    24.  
    25.      
    26.  
    27.     // Also creates a grandparent (camGrandparent) which can be rotated with localEulerAngles.y
    28.  
    29.     // This node allows an arbitrary heading to be added to the gyroscope reading
    30.  
    31.     // so that the virtual camera can be facing any direction in the scene, no matter what the phone's heading
    32.  
    33.      
    34.  
    35.     static var gyroBool : boolean;
    36.  
    37.     private var gyro : Gyroscope;
    38.  
    39.     private var quatMult : Quaternion;
    40.  
    41.     private var quatMap : Quaternion;
    42.  
    43.      
    44.  
    45.     function Awake() {
    46.  
    47.         // find the current parent of the camera's transform
    48.  
    49.         var currentParent = transform.parent;
    50.  
    51.         // instantiate a new transform
    52.  
    53.         var camParent = new GameObject ("camParent");
    54.  
    55.         // match the transform to the camera position
    56.  
    57.         camParent.transform.position = transform.position;
    58.  
    59.         // make the new transform the parent of the camera transform
    60.  
    61.         transform.parent = camParent.transform;
    62.  
    63.         // make the original parent the grandparent of the camera transform
    64.  
    65.         //camParent.transform.parent = currentParent;
    66.  
    67.         // instantiate a new transform
    68.  
    69.         var camGrandparent = new GameObject ("camGrandParent");
    70.  
    71.         // match the transform to the camera position
    72.  
    73.         camGrandparent.transform.position = transform.position;
    74.  
    75.         // make the new transform the parent of the camera transform
    76.  
    77.         camParent.transform.parent = camGrandparent.transform;
    78.  
    79.         // make the original parent the grandparent of the camera transform
    80.  
    81.         camGrandparent.transform.parent = currentParent;
    82.  
    83.            
    84.  
    85.         // check whether device supports gyroscope
    86.  
    87.  
    88.        //Removed Unity version Checks to support unity 4 - dustin.hagen
    89.         gyroBool = SystemInfo.supportsGyroscope;
    90.  
    91.  
    92.  
    93.        
    94.  
    95.         if (gyroBool) {
    96.  
    97.             gyro = Input.gyro;
    98.  
    99.             gyro.enabled = true;
    100.  
    101.             #if UNITY_IPHONE
    102.  
    103.                     camParent.transform.eulerAngles = Vector3(90,90,0);
    104.  
    105.                
    106.  
    107.                         if (Screen.orientation == ScreenOrientation.LandscapeLeft) {
    108.  
    109.                            quatMult = Quaternion(0,0,1,0); //**
    110.  
    111.                         } else if (Screen.orientation == ScreenOrientation.LandscapeRight) {
    112.  
    113.                            quatMult = Quaternion(0,0,1,0); //**
    114.  
    115.                         } else if (Screen.orientation == ScreenOrientation.Portrait) {
    116.  
    117.                            quatMult = Quaternion(0,0,1,0); //**
    118.  
    119.                         } else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
    120.  
    121.                            quatMult = Quaternion(0,0,1,0); // Unable to build package on upsidedown
    122.  
    123.                         }
    124.  
    125.             #endif
    126.  
    127.             #if UNITY_ANDROID
    128.  
    129.                     camParent.transform.eulerAngles = Vector3(90,90,0);
    130.  
    131.                
    132.  
    133.                         if (Screen.orientation == ScreenOrientation.LandscapeLeft) {
    134.  
    135.                            quatMult = Quaternion(0,0,1,0); //**
    136.  
    137.                         } else if (Screen.orientation == ScreenOrientation.LandscapeRight) {
    138.  
    139.                            quatMult = Quaternion(0,0,1,0); //**
    140.  
    141.                         } else if (Screen.orientation == ScreenOrientation.Portrait) {
    142.  
    143.                            quatMult = Quaternion(0,0,1,0); //**
    144.  
    145.                         } else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
    146.  
    147.                            quatMult = Quaternion(0,0,1,0); // Unable to build package on upsidedown
    148.  
    149.                         }
    150.  
    151.             #endif
    152.  
    153.             Screen.sleepTimeout = SleepTimeout.NeverSleep;
    154.  
    155.         } else {
    156.  
    157.             #if UNITY_EDITOR
    158.  
    159.                 //print("NO GYRO");
    160.  
    161.             #endif
    162.  
    163.         }
    164.  
    165.     }
    166.  
    167.      
    168.  
    169.     function Update () {
    170.  
    171.         if (gyroBool) {
    172.  
    173.             #if UNITY_IPHONE
    174.  
    175.                 quatMap = gyro.attitude;
    176.  
    177.             #endif
    178.  
    179.             #if UNITY_ANDROID
    180.  
    181.                 quatMap = Quaternion(gyro.attitude.x,gyro.attitude.y,gyro.attitude.z,gyro.attitude.w);
    182.  
    183.             #endif
    184.  
    185.             transform.localRotation = quatMap * quatMult;
    186.  
    187.         }
    188.  
    189.     }
  21. Mantas Puida

    Mantas Puida

    Unity Technologies

    Joined:
    Nov 13, 2008
    Messages:
    1,175
    Aren't Android and iPhone code paths the same now? :)
  22. Utopya

    Utopya

    New Member

    Joined:
    Jan 31, 2013
    Messages:
    2
    How about devices without gyro? Is there anybody who can give me some tips to write someting that works with accelerometer and compass?
  23. jhybe

    jhybe

    New Member

    Joined:
    Feb 3, 2013
    Messages:
    3
    Thanks for this script
    works great on iPad 2.

    Just an issue to move the player using the characters prefab.

    If I put the script onto my camera, it moves according to my iPad, but the character don't rotate.
    So, I puted the script directly onto the character, but when I rotate the iPad, the capsule rotate also.. so the height of the camera is not always the same.

    How can I do? Do I have to put the script on my camera, and make another script so that when I rotate the capsule rotate as well?

    Thanks, Jonathan
  24. KareemErgawy

    KareemErgawy

    New Member

    Joined:
    Jan 11, 2013
    Messages:
    8
    Great Work, I used it on my Android device and it worked perfectly.
  25. charmandermon

    charmandermon

    Member

    Joined:
    Dec 4, 2011
    Messages:
    150
    Can anyone help figure how to do a proper gyro orientation calibration. Turning the gyro off then on again doesn't reset it anymore since the latest 2 unity builds.

    Any help would be greatly appreciated the math is beyond my skills. To be clear I'm looking for a way to calibrate the camera so it works while a person is laying down then if they stand up and move positions they press calibrate and it readjusts the cameras orientation. Also I am not referring to actual device orientation (landscape, portrait).
    Last edited: Mar 19, 2013
  26. Mantas Puida

    Mantas Puida

    Unity Technologies

    Joined:
    Nov 13, 2008
    Messages:
    1,175
    Unity 4.1 should fix gyro restart problem.
  27. charmandermon

    charmandermon

    Member

    Joined:
    Dec 4, 2011
    Messages:
    150
    Thanks mantas for the quick reply.
    I read through the release notes and it doesn't mention it anywhere. Also the gyro reset (turning it off and on) was more of a hack and only calibrates one of the axis' not all 3. Honestly a better solution is to add a calibration formula. Anyone have any ideas on how to do it? Thanks!
  28. Mantas Puida

    Mantas Puida

    Unity Technologies

    Joined:
    Nov 13, 2008
    Messages:
    1,175
    Sorry my bad. It is scheduled for 4.2.
  29. QingRuoChen

    QingRuoChen

    New Member

    Joined:
    Jan 17, 2013
    Messages:
    2
  30. leonida

    leonida

    New Member

    Joined:
    Jul 3, 2012
    Messages:
    1
    thanks!
    can someone post a sample scene where he uses the correct script for unity4?
    I tried it on Android but the view does not follow the gyroscope.

    how to calculate rotation of axis in ScreenOrientation.LandscapeLeft??
    Last edited: Apr 15, 2013
  31. Nooch

    Nooch

    New Member

    Joined:
    Dec 31, 2011
    Messages:
    18
    Thanks so much for this script, phoberman! :cool:
    Fantastic stuff!! (Yeah I know I'm 2 years late).

    I wanted to share a small modification I did, in order to fix the issue of camera stuttering.
    On iPad2, I noticed every 1-2 seconds the camera stutters while rotating (not sure about other devices).
    This script isn't causing the problem, it's something with Unity itself. Perhaps this was fixed in later versions, I'm not sure (on 3.5.7 here).

    That said, we can apply a small change here in order to fix it:

    Code (csharp):
    1.  
    2. var currentRot : Quaternion;
    3. var newRot : Quaternion;
    4. var smoothingAmount : float = 10;
    5.  
    6. ...
    7.  
    8. function Update()
    9. {
    10.     if (gyroBool)
    11.     {
    12.         // Get current rotation
    13.         currentRot = transform.localRotation;
    14.    
    15.         ... (existing code) ...
    16.        
    17.         // Get new rotation, apply smoothed result to camera
    18.         newRot = quatMap * quatMult;
    19.         transform.localRotation = Quaternion.Lerp(currentRot, newRot, Time.smoothDeltaTime * smoothingAmount);
    20.     }
    21. }
    22.  
    This smooths the rotation and eliminates the stutters. This does introduce a tiny amount of lag, but I think it's acceptable, and results overall look nicer. You can adjust this by tweaking the smoothingAmount value. A lower number will smooth over a longer period. A higher number will be quicker, but if you get too high (like 20 or so), you'll start to see stuttering again. So feel free to try it for yourself and find a nice value. It works well for me, but YMMV of course. :)
  32. aroha

    aroha

    Member

    Joined:
    Jan 8, 2013
    Messages:
    17
    Following script ported to C#, tested for all 4 orientations on Unity 4.1, Android and iOS.
    Android: Galaxy S3 4.1.1, Sony Xperia 4.0.4, ASUS TF101 Tablet 4.0.3
    iOS: iPad2 and iPhone5

    Update: I realized that the Android orientations were correct but the "direction" wasn't. It was just by chance the direction I was sitting at my desk aligned with the gyroscope when I first opened the Unity scene. Unlike my tests on my iOS devices, the "front" of the scene did not automatically adjust itself to the direction the phone was pointing when I opened my scene. I updated the script below to Perry's latest script from page 4 that supposedly fixes this issue with using a grandparent game object but that didn't work on my Galaxy S3. I updated the code below to use a scroll bar so you can manually adjust the Y axis rotation to get the right direction.

    Code (csharp):
    1. // Gyroscope-controlled camera for iPhone  Android revised 2.26.12
    2. // Perry Hoberman <hoberman@bway.net>
    3. //
    4. // Usage:
    5. // Attach this script to main camera.
    6. // Note: Unity Remote does not currently support gyroscope.
    7. //
    8. // This script uses three techniques to get the correct orientation out of the gyroscope attitude:
    9. // 1. creates a parent transform (camParent) and rotates it with eulerAngles
    10. // 2. for Android (Samsung Galaxy Nexus) only: remaps gyro.Attitude quaternion values from xyzw to wxyz (quatMap)
    11. // 3. multiplies attitude quaternion by quaternion quatMult
    12. // Also creates a grandparent (camGrandparent) which can be rotated with localEulerAngles.y
    13. // This node allows an arbitrary heading to be added to the gyroscope reading
    14. // so that the virtual camera can be facing any direction in the scene, no matter what the phone's heading
    15. //
    16. // Ported to C# by Simon McCorkindale <simon <at> aroha.mobi>
    17.  
    18. using UnityEngine;
    19.  
    20. public class GyroCam : MonoBehaviour
    21. {
    22.     private bool gyroBool;
    23.     private Gyroscope gyro;
    24.     private Quaternion rotFix;
    25.  
    26.     public void Start ()
    27.     {
    28.         Transform currentParent = transform.parent;
    29.         GameObject camParent = new GameObject ("GyroCamParent");
    30.         camParent.transform.position = transform.position;
    31.         transform.parent = camParent.transform;
    32.         GameObject camGrandparent = new GameObject ("GyroCamGrandParent");
    33.         camGrandparent.transform.position = transform.position;
    34.         camParent.transform.parent = camGrandparent.transform;
    35.         camGrandparent.transform.parent = currentParent;
    36.  
    37.         #if UNITY_3_4
    38.         gyroBool = Input.isGyroAvailable;
    39.         #else
    40.         gyroBool = SystemInfo.supportsGyroscope;
    41.         #endif
    42.    
    43.         if (gyroBool) {
    44.          
    45.             gyro = Input.gyro;
    46.             gyro.enabled = true;
    47.          
    48.             if (Screen.orientation == ScreenOrientation.LandscapeLeft) {
    49.                 camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
    50.             } else if (Screen.orientation == ScreenOrientation.Portrait) {
    51.                 camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
    52.             } else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
    53.                 camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
    54.             } else if (Screen.orientation == ScreenOrientation.LandscapeRight) {
    55.                 camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
    56.             } else {
    57.                 camParent.transform.eulerAngles = new Vector3 (90, 180, 0);
    58.             }
    59.  
    60.             if (Screen.orientation == ScreenOrientation.LandscapeLeft) {
    61.                 rotFix = new Quaternion (0, 0, 1, 0);
    62.             } else if (Screen.orientation == ScreenOrientation.Portrait) {
    63.                 rotFix = new Quaternion (0, 0, 1, 0);
    64.             } else if (Screen.orientation == ScreenOrientation.PortraitUpsideDown) {
    65.                 rotFix = new Quaternion (0, 0, 1, 0);
    66.             } else if (Screen.orientation == ScreenOrientation.LandscapeRight) {
    67.                 rotFix = new Quaternion (0, 0, 1, 0);
    68.             } else {
    69.                 rotFix = new Quaternion (0, 0, 1, 0);
    70.             }
    71.  
    72.             //Screen.sleepTimeout = 0;
    73.         } else {
    74.             #if UNITY_EDITOR
    75.             print("NO GYRO");
    76.             #endif
    77.         }
    78.     }
    79.    
    80.     public void Update ()
    81.     {
    82.         if (gyroBool  this.gameObject.camera.enabled) {
    83.             Quaternion quatMap;
    84.             #if UNITY_IPHONE
    85.                 quatMap = gyro.attitude;
    86.             #elif UNITY_ANDROID
    87.                 quatMap = new Quaternion(gyro.attitude.x,gyro.attitude.y,gyro.attitude.z,gyro.attitude.w);
    88.             #endif
    89.             transform.localRotation = quatMap * rotFix;
    90.         }
    91.     }
    92.  
    93.     float scroll = 180f;
    94.  
    95.     public void OnGUI ()
    96.     {
    97.         if (gyroBool  this.gameObject.camera.enabled) {
    98.             // Add scrollbar to rotate around Y axis 0-360 for manual adjustment
    99.             scroll = GUI.VerticalScrollbar (new Rect (Screen.width - 35, 25, 30, Screen.height / 2), scroll, 1.0f, 0.0f, 360.0f);
    100.         }
    101.         if (GUI.changed) {
    102.             transform.parent.eulerAngles = new Vector3 (transform.parent.eulerAngles.x, scroll, transform.parent.eulerAngles.z);
    103.         }
    104.     }
    105. }
    106.  
    Last edited: May 5, 2013
  33. BooBi

    BooBi

    Member

    Joined:
    Jan 18, 2010
    Messages:
    521
    Does anyone managed to link it to the FPS Controller?
    I would like to use it for my camera and use the left joystick to move forward, I can't manage to link the rotation X of the camera to my FPS Controller. I should probably split the script in two scripts one managing the Yaw for the fps controller and the other managing the pitch and roll for the camera. I don't get how to manage that by playing with the quaternions without being too extensive on the performances...

    Any help would be much appreciated!
    Thanks in advance
    Last edited: May 14, 2013
  34. RebelFuture

    RebelFuture

    New Member

    Joined:
    Nov 28, 2012
    Messages:
    1

    This was VERY helpful for me. Thank you. Below I am posting the code I wrote after learning from your post. This class moves the camera Left, Right, Up, Down based upon the gyro.rotationRate. While moving the camera keeps itself focused on it's target. This makes for some interesting movement when viewing a 2D UI in perspective mode.

    Code (csharp):
    1. using UnityEngine;
    2. using System.Collections;
    3.  
    4. public class GyroCameraControl : IgnoreTimeScale
    5. {
    6.     private bool gyroBool;
    7.     private Gyroscope gyro;
    8.    
    9.     private Transform mTrans;
    10.     private Vector2 mRot = Vector2.zero;
    11.    
    12.     // the camera will continue to look at this as it moves, keep it in perspective mode
    13.     public GameObject cameraTarget;
    14.    
    15.     void Start()
    16.     {
    17.         gyroBool = SystemInfo.supportsGyroscope;
    18.        
    19.         if ( gyroBool ) {
    20.            
    21.             mTrans = transform;
    22.            
    23.             gyro = Input.gyro;
    24.             gyro.enabled = true;
    25.         } else {
    26.             print( "NO GYRO" );
    27.         }
    28.     }
    29.  
    30.     void Update ()
    31.     {
    32.         if (gyroBool) {
    33.             float delta = UpdateRealTimeDelta();
    34.            
    35.             mRot = Vector2.Lerp(mRot, new Vector2( Input.gyro.rotationRate.y, Input.gyro.rotationRate.x ), delta * 5f);
    36.    
    37.             transform.localPosition = new Vector3( mRot.x*10f, mRot.y*10f, mTrans.localPosition.z );
    38.             transform.LookAt( cameraTarget.transform.position );
    39.         }
    40.     }
    41. }
  35. Budgieboy

    Budgieboy

    Member

    Joined:
    Sep 6, 2012
    Messages:
    25
    This doesn't work for me, what do I need to do?

    I'm trying to create a moving gyro camera with boundaries and I've tried scrips all over Google with hardly even close success and I've spent days, please someone help me! :(
  36. Siusega

    Siusega

    New Member

    Joined:
    Mar 5, 2013
    Messages:
    2
    Works on Asus Transformer!. After 7 hours of trying to fix the first version. Thanks!
  37. Sanky

    Sanky

    New Member

    Joined:
    Jan 16, 2013
    Messages:
    1
    hey phoberman i want know that is this script works with android device because i am trying to do this on android device.
  38. sorushe.mehre

    sorushe.mehre

    Member

    Joined:
    Aug 12, 2013
    Messages:
    4
    i test this script and work good on many android devices but does not work on android 4.2!!!
    any one has similar problem?
    any one can help to solve this issue
  39. Loyalwater

    Loyalwater

    Member

    Joined:
    Nov 1, 2013
    Messages:
    2
    Hi Everyone !!

    One quick question ... hope some kind soul would help .. How can we invert the roll? When the phone turns clockwise, the gyro turns anti clockwise and vice versa. Left Right Up n DOwn are working perfectly fine. I know that the roll behavior I want to reverse is the normal behavior. I have seen it in gyro enabled games. But I want to reverse it. Can some one please help me with the math here. What do I need to change?
  40. am_

    am_

    Member

    Joined:
    Feb 4, 2014
    Messages:
    3
    Thanks to aroha for sharing your script, works really good! I get an intial offset on the camera though (seems to be rotated/moved 90 degrees off to the side on my ipad) I had to hardcode the initial offset for this to work on my ipad, any idea on how to make a better universal solution?
  41. franktinsley

    franktinsley

    Member

    Joined:
    Jul 1, 2010
    Messages:
    93
  42. dsimoes12

    dsimoes12

    Member

    Joined:
    Apr 16, 2014
    Messages:
    15
    Hello everyone,

    I've tried 3 or 4 gyro camera scripts in the last few weeks but none of them really satisfied me completely. I would fix them myself but there are some details I dont quite understand.

    One of the bugs that is really annoying me is when I start the game, the camera always smoothly rotates about 90 degrees to the right (on Y)! Has anyone experienced this before? Is there a way to force a calibration of the gyro so that when the game starts thr camera is facing the way it is facing on the editor?

    Using Unity 4.3, developing for Android and testing on Nexus 5.

    thanks
    Last edited: May 1, 2014
  43. anivader1789

    anivader1789

    Member

    Joined:
    Sep 3, 2013
    Messages:
    2
    Works well. Thanks for sharing!!