One of the biggest challenges with HoloLens development and Unity is getting the position and rotation of holographic objects correctly. Let’s say you want to build an application that shows a menu in front of you and it should always been rotated towards you? That can be tricky.
You need to understand that when your application fires up in the device, the position of the device in the real world is seen as (0,0,0) and a rotation depending on the angle and direction you are looking.
To get the menu in front of you is setting it’s initial position at for example (0,0,3). That means 3 meters in forward (z) direction. This is something you would do in the transformation settings with components in Unity or through coding.
But as soon as you start moving around and looking into other directions the position and rotation of the HoloLens device changes.
To get the menu again in front of you, you will need to set the position and rotation of the menu. The position and rotation are of course based on the position of the HoloLens device and the direction you are looking into.
Positioning the menu
To get the menu again in front of you we need to set the position again. We still want it to appear 3 meters in front of us. Therefor we need the position of the HoloLens and add an additional 3 meters to the forward (z) direction. To get the position of the device we need the transformation component of the main camera. This can be achieved with the following code:
GameObject menu; // Get a reference to the menu gameobject Vector3 devicePosition = Camera.main.transform.position; menu.transform.position = new Vector3(devicePosition.x, devicePosition.y, devicePosition.z + 3);
Simple right? But hey… The rotation is still weird. Your menu seems to be positioned correctly in front of you except that it is rotated. It seems to be still rotated to its initial location. So how do we resolve this?
Rotate the menu towards you
You will need to understand quaternions. Or actually you don’t have to. Quaternions are difficult to understand and to get a grab on. Simply explained a quaternion consists of 4 values. The first values x, y, z define the axis about which a rotation is needed. The fourth value called w represents the amount of rotation around that axis. If you look at the transformation object of a GameObject in Unity you would expect that x,y,z are represented by the rotation part. But that is not the case. the component expects you to enter angles. Those angles are then transformed through difficult calculations using quaternions to determine the correct rotation. If you really want to learn more about quaternions and you are not afraid of math read this blog post. But for now this is all you need to know.
In Unity we have a struct called Quaternion. It contains some powerful and nifty functions which help you to correctly rotate holographic objects. One of them is called “Quaternion.FromToRotation() and is used to get a gaze cursor correctly positioned on the surface area of meshes.
But in our case we need to rotate the menu in such a way that it rotates towards you. The HoloLens device has something called the gaze. The gaze is the direction in which you (or actually the HoloLens device) is facing. The Quaternion struct has a great method called Quaternion.LookRotation(). It expects a Vector3 direction to look in. That’s great! Because the gaze direction is exactly what we need. To get the direction of the gaze (forward) we need the forward property of the transformation component of the main camera.
So we use the following code to rotate the menu towards you.
GameObject menu; // Get a reference to the menu gameobject Vector3 gazeDirection = Camera.main.transform.forward; menu.transform.rotation = Quaternion.LookRotation(gazeDirection);
And there we are! We now have set the position and rotation of the menu. Keep in mind that when you want to place the menu along one of the edges of the viewport of the device, it would be handy to actually rotate it a little bit more in your direction. The gaze actually points straight forward. Let’s say you place it on the left or right you want to rotate the menu a little bit around the y axis. For this Quaternion has a specific function called Quaternion.AngleAxis(). It expects the Axis and an angle to execute a rotation.
As you have seen it is actually not difficult to position and rotate a menu in front of you. Understanding of positioning and rotation of created holographic objects with HoloLens is needed. You will need to have some understanding of Quaternions. But Unity delivers a powerful set of functions to help you with these kind of tasks using the Quaternion struct.