Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 12 Next capture
2021 2022 2023
1 capture
12 Jun 22 - 12 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
5
Question by wbknox · Nov 02, 2016 at 09:07 PM · iosgyroscopegyroworld space

Finding physical world x,y,z with respect to an iOS device camera

[This is a problem and solution.]

Currently, if you Google "unity ios attitude" you'll find considerable confusion about how to understand an iOS device's attitude (i.e. orientation) in physical space, in a way that can be used in Unity. You'll also find some scripts that purport to be solutions to variants of this problem. It seems that some work, based on comments on those pages.

My specific need was to know the vectors for up, forward, and right within the physical world I'm in, given with respect to the iOS device camera.

The obvious solution fails

One obvious thing to try is to define a game object and set its transform.rotation as follows:

 transform.rotation = Input.gyro.attitude;

With this strategy, transform.up, transform.right, and transform.forward would seemingly give the vectors in Unity-world space that correspond to the iOS device's attitude in physical-world space. I recommend testing this direct assignment of rotation on a Unity camera (put it in the a script's Update() function on that camera object). You should see that 2 of 3 rotation axes move in the opposite direction than what is needed to have the Unity camera mimic the phone's camera. As you'll see below, multiplying the corresponding Euler angles by -1 is only part of the solution.

After I studied quaternions (more interesting than the mysterious headache they seemed to be), tried almost exhaustively searching parameters for different manipulations on quaternions and Euler angles, and conducted an embarrassing amount of unrigorous trial and error, I now have the following solution.

Solution for finding vectors describing physical world orientation from iOS device's perspective

(1) Create an empty game object and name it "PhoneDummy". On PhoneDummy, create a script with the following update code.

 void Update () {
     Quaternion deviceRotation = Input.gyro.attitude;
     transform.eulerAngles = new Vector3 (
         -1 * deviceRotation.eulerAngles.x,
         -1 * deviceRotation.eulerAngles.y,
         deviceRotation.eulerAngles.z);
 }

If this game object was a camera (which it doesn't need to be), you would see that it changes its rotation correctly with respect to fixed objects, but it is rotated 90 degrees along the forward axis. The next part accounts for that remaining error while computing vectors for the physical world's orientation.

(2) The orientation of the physical world, within the local space of the iOS device camera, can then be found by

 Vector3 upVec = phoneDummy.transform.InverseTransformDirection( -1f * Vector3.forward);
 Vector3 rightVec = phoneDummy.transform.InverseTransformDirection( 1f * Vector3.up);
 Vector3 forwardVec = phoneDummy.transform.InverseTransformDirection( -1f * Vector3.right);

Note that the local space of the Unity camera isn't actually used to calculate these.

Also, just to be clear, at some point prior phoneDummy would have been assigned the return value of

 GameObject.Find ("PhoneDummy");

These vectors can be used to move objects so that they maintain the same rotation with respect to the physical world. To see an example—and in doing so test this code on your iOS device—create an object with directionality (e.g., a tree). Set that object's parent as the Unity camera, move the object's position to be centered in the camera, and attach the following script to the object:

 using UnityEngine;
 using System.Collections;
 public class KeepRotInPhysWorld : MonoBehaviour {
 
     GameObject phoneDummy;
 
     void Start () {
         phoneDummy = GameObject.Find ("PhoneDummy");
     }
 
     void Update () {
         /**
          * Use phoneDummy rotation to find actual direction vectors relative to the phone
          */
         Vector3 upVec = phoneDummy.transform.InverseTransformDirection(-1f * Vector3.forward);
         Vector3 rightVec = phoneDummy.transform.InverseTransformDirection(1f * Vector3.up);
         Vector3 forwardVec = phoneDummy.transform.InverseTransformDirection(-1f * Vector3.right);
 
         transform.LookAt (transform.position + forwardVec, upVec);
     }
 }

When you run this on your iOS device, you should see the 3D object maintain its rotation with respect to the physical world.

An alternative

If you specifically want to control the Unity camera to mimic the phone camera—so that its rotation in world space is the same as the iOS device's camera's rotation in physical space—check out the script here, which worked well for me in brief testing: https://forum.unity3d.com/threads/sharing-gyroscope-camera-script-ios-tested.241825/. You may want to test it with a scene with visual variety, even if that's just a rectangular-prism room with different colors for each wall.

How Unity's internal team could save us from this mess

Both solutions are messy and quite difficult to wrap your head around. It's deeply unfortunate that Unity doesn't redefine Input.gyro.attitude such that setting a Unity camera's rotation by

 transform.rotation = Input.gyro.attitude;

makes the Unity camera mimic the phone camera. The current output of Input.gyro.attitude could still be available as Input.gyro.rawAttitude for the crazy folks that want to use that.

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image wbknox · Apr 03, 2018 at 02:56 PM 0
Share

This same solution is working for Android, except that you need to enable the gyro before querying it for attitude. A general solution for iOS and Android is below, as an expansion of the "PhoneDummy" object's script. (Everything else written above stays the same.)

 using UnityEngine;
 using System.Collections;
 
 public class $$anonymous$$imicPhoneCam : $$anonymous$$onoBehaviour {
 
     private Gyroscope gyro;
     private bool gyroEnabled = false;
 
     void Start () {
         gyroEnabled = EnableGyro();
         //Debug.Log ("Gyro enabled: " + gyroEnabled);
     }
 
     private bool EnableGyro() {
         if (SystemInfo.supportsGyroscope) {
             gyro = Input.gyro;
             gyro.enabled = true;
             return true;
         }
         return false;
     }
 
     void Update () {    
         if (gyroEnabled) {
             Quaternion deviceRotation = gyro.attitude;
             transform.eulerAngles = new Vector3(
                 -1 * deviceRotation.eulerAngles.x,
                 -1 * deviceRotation.eulerAngles.y,
                 deviceRotation.eulerAngles.z);
         }
 
     }
         
 }

2 Replies

· Add your reply
  • Sort: 
avatar image
1

Answer by Romaleks360 · Jun 15, 2019 at 06:42 PM

Isn't it written in the manual?

 private static Quaternion GyroToUnity(Quaternion q)
     {
         return new Quaternion(q.x, q.y, -q.z, -q.w);
     }

https://docs.unity3d.com/ScriptReference/Gyroscope.html

But yeah it's still anti-intuitive and useless

Comment
Add comment · Show 1 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Bunny83 · Jun 17, 2019 at 11:58 AM 0
Share

Well, the orientation of a device in the real world is something completely different from the virtual world inside Unity. In mathematics we usually use a right handed system and that's also used by the gyro hardware of your device. Unity uses a left handed coordinate system in the virtual world. GyroToUnity does this transformation. $$anonymous$$eep in $$anonymous$$d that there's not only one valid way how to translate the real world orientation into Unity's virtual space.

avatar image
0

Answer by HanSoloYolo · Jul 23, 2017 at 09:25 PM

Hello,

I am having the same issue, but am developing for Android. How would I modify the following Script to allow me to transform.localRotation of GyroControl (My parent game object) to be offset the current gyro.attitude. Allowing the user to look up and reset the scene to their current Z axis or direction they are facing. I would like to use a if (Input.touchCount == 2) () to recenter the original scene perspective on the current gyro.attitude.

 using UnityEngine;
 public class GyroController : MonoBehaviour 
 {
     private bool gyroEnabled;
     private Gyroscope gyro;
     private GameObject GyroControl;
     private Quaternion rot;
 
     private void Start () 
     {
         GyroControl = new GameObject ("Gyro Control");
         GyroControl.transform.position = transform.position;
         transform.SetParent (GyroControl.transform);
         gyroEnabled = EnableGyro();
 
     }
 
 
     private bool EnableGyro()
     {
         if (SystemInfo.supportsGyroscope) 
             {
             gyro = Input.gyro;
             gyro.enabled = true;
             GyroControl.transform.rotation = Quaternion.Euler(90f, -90f, 0f);
             rot = new Quaternion(0, 0, 1, 0);
             return true;
             }
         return false;
     }
 
     private void Update () 
     {
         if (gyroEnabled) 
         {
             transform.localRotation = gyro.attitude * rot;
         }
     }
 }

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

93 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Get single axis from gyroscopic input (iOS) 0 Answers

IOS gyro trick ? 0 Answers

Ignore gyroscope yaw 0 Answers

How to make GameObject follow phone's gyro? 0 Answers

Gyroscope Controls for FPS 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges