Notifications
Article
Gentle Introduction to Hololens
Published 2 months ago
49
1
Beginners guide to Hololens development using Mixed Reality Toolkit
Hololens is now available for quite some time in market and developer across the globe are trying to make best apps on it. After all, it is the most publicized mixed reality device.
When I first saw the promotional video of Hololens, I literally jumped out of my seat and paused the video to make sure that is that even real? I mean how can is this even possible; yes I saw this in Iron Man, but damn!!.
Then I got a chance to actually lay hands on Hololens and I was disappointed, why?? 1. The field of view. 2. Only two gesture - Air tap and bloom. But this didn't kill my curiosity completely in this $3000 device so I started making demos and prototypes on Hololens and they came out pretty nice.

Some of the fields where Hololens can make huge impacts are Manufacturing and Assistance.
So let’s code.
Now we can write code for everything i.e write our own logic if user gazed someplace or air tapped on a game object, or we can use a mixed reality library that has functions and interface that can make our life damn easy. And we are going to use the library - Mixed Reality Toolkit earlier known as Holotoolkit.
  • Create a new Unity project Hololens101, download Unity SDK from here and as I am using Unity3D version 5.6.1 f1 so I am using HoloToolkit-Unity-Tests-v1.5.8.0.
  • Create an empty folder - Hololens101, create two more folders 1. Scene 2. Scripts in Hololens101.
  • Create a new scene - MainScene in 'Scene' folder created above
  • Open build settings and switch the project to - Windows Store.
  • Click player settings and update company name and product name.
  • Open in player settings and check Virtual Reality Supported, add Windows Holographic.
  • Export the SDK in the project that we have created. And we will have unity project something like the image below.
  • Go into HolotoolKit>Input>Prefabs and place InputManager and HololensCamera in the scene view (HololensCamera at 0,0,0). Also, delete MainCamera from the scene as we have added HololensCamera in the scene.
  • Go into HolotoolKit>Input>Prefabs>Cursor and place Cursor in the scene view.
  • Create 3 cubes with scale 0.1, place Cube1 at (-0.2,0,2) - Cube2 at (0,0,2) - Cube3 at (0.2,0,2)
  • Implementing drag is quite simple as there is already a script HandDraggable.cs in SDK. Click on Cube1 and go to the inspector, click add component and search for HandDraggable.cs.
  • We will implement rotation and scale. Create c# script - Rotate.cs in scripts folder that we had created in Hololens101 and drop it on Cube2.
  • Now Mixed Reality Toolkit has provided many adapters that make our life as a developer very easy. If you go to this link you will find many interfaces that we can use to take input. We will use IManipulationHandler and IInputHandler
  • Let us discuss IInputHandler, this interface provides two methods : -
  1. OnInputDown - Called when the user taps on the game object.
  2. OnInputUp - Called when the user releases the tap on the game object.
  3. Both these methods take InputEventData as an argument which has BaseEventData as its parent class.
public void OnInputDown(InputEventData eventData) { } public void OnInputUp(InputEventData eventData) { }
  • IManipulationHandler - This interface has four methods and they are used to tackle tap and move gesture. It has four methods
  1. OnManipulationStarted - Called when the user taps on the game object and start moving his tapped hand.
  2. OnManipulationUpdated - Called when the user is moving his tapped finger.
  3. OnManipulationCompleted - Called when user manipulation is completed i.e when user releases his finger.
  4. OnManipulationCanceled - Called when this manipulation is cancelled.
public void OnManipulationCanceled(ManipulationEventData eventData) { } public void OnManipulationCompleted(ManipulationEventData eventData) { } public void OnManipulationStarted(ManipulationEventData eventData) { } public void OnManipulationUpdated(ManipulationEventData eventData) { }
Important  - The trick is that we will push the game object in a singleton instance of InputManager so that until user's tap is released that game object will stay the point of input even if the user gazes at someplace else while manipulation.
private IInputSource currentInputSource = null; private uint currentInputSourceId; public void OnInputDown(InputEventData eventData) { currentInputSource = eventData.InputSource; currentInputSourceId = eventData.SourceId; InputManager.Instance.PushModalInputHandler(gameObject); InputManager.Instance.RaiseManipulationStarted(currentInputSource, currentInputSourceId, transform.position); } public void OnInputUp(InputEventData eventData) { InputManager.Instance.RaiseManipulationCompleted(currentInputSource, currentInputSourceId, transform.position); InputManager.Instance.PopModalInputHandler(); }
  • What we did in the above step is that we saved the game object that we have received via eventadata.InputSource in the IInputSource variable, its SourceId into currentInputSourceId, and passed that game object in PushModalInputHandler and then we raised manipulation by calling RaiseManipulationStarted.
  • Replace the OnManipulationUpdated with the code below
public void OnManipulationUpdated(ManipulationEventData eventData) { float multiplier = 1.0f; float cameraLocalYRotation = Camera.main.transform.localRotation.eulerAngles.y; if (cameraLocalYRotation > 270 || cameraLocalYRotation < 90) multiplier = -1.0f; var rotation = new Vector3(0, eventData.CumulativeDelta.x * multiplier); transform.Rotate(rotation * 10, Space.World); }
  • Now your class will look like the code below.
using HoloToolkit.Unity.InputModule; using UnityEngine; using IInputHandler = HoloToolkit.Unity.InputModule.IInputHandler; using IManipulationHandler = HoloToolkit.Unity.InputModule.IManipulationHandler; public class Rotate : MonoBehaviour, IInputHandler, IManipulationHandler { private IInputSource currentInputSource = null; private uint currentInputSourceId; public void OnInputDown(InputEventData eventData) { currentInputSource = eventData.InputSource; currentInputSourceId = eventData.SourceId; InputManager.Instance.PushModalInputHandler(gameObject); InputManager.Instance.RaiseManipulationStarted(currentInputSource, currentInputSourceId, transform.position); } public void OnInputUp(InputEventData eventData) { InputManager.Instance.RaiseManipulationCompleted(currentInputSource, currentInputSourceId, transform.position); InputManager.Instance.PopModalInputHandler(); } public void OnManipulationCanceled(ManipulationEventData eventData) { } public void OnManipulationCompleted(ManipulationEventData eventData) { } public void OnManipulationStarted(ManipulationEventData eventData) { } public void OnManipulationUpdated(ManipulationEventData eventData) { float multiplier = 1.0f; float cameraLocalYRotation = Camera.main.transform.localRotation.eulerAngles.y; if (cameraLocalYRotation > 270 || cameraLocalYRotation < 90) multiplier = -1.0f; var rotation = new Vector3(0, eventData.CumulativeDelta.x * multiplier); transform.Rotate(rotation * 10, Space.World); } }
To implement scale, create a c# script in script folder and paste the below code in it.
using HoloToolkit.Unity.InputModule; using UnityEngine; using IInputHandler = HoloToolkit.Unity.InputModule.IInputHandler; using IManipulationHandler = HoloToolkit.Unity.InputModule.IManipulationHandler; public class Scale : MonoBehaviour, IInputHandler, IManipulationHandler { private IInputSource currentInputSource = null; private uint currentInputSourceId; private Vector3 currentScale; public void OnInputDown(InputEventData eventData) { currentInputSource = eventData.InputSource; currentInputSourceId = eventData.SourceId; currentScale = transform.localScale; InputManager.Instance.PushModalInputHandler(gameObject); InputManager.Instance.RaiseManipulationStarted(currentInputSource, currentInputSourceId, transform.position); } public void OnInputUp(InputEventData eventData) { InputManager.Instance.RaiseManipulationCompleted(currentInputSource, currentInputSourceId, transform.position); InputManager.Instance.PopModalInputHandler(); } public void OnManipulationCanceled(ManipulationEventData eventData) { } public void OnManipulationCompleted(ManipulationEventData eventData) { } public void OnManipulationStarted(ManipulationEventData eventData) { } public void OnManipulationUpdated(ManipulationEventData eventData) { Vector3 scale = currentScale * eventData.CumulativeDelta.x + currentScale; transform.localScale = scale; } }
  • Now I am not going to explain what I am doing in this class, as the code is self-explanatory (same approach that we used in Rotate.cs). Drop this class on Cube3 and test it.
  • The only thing is left to test this on hololens. We have already done all the initial settings to build this project for hololens at the beginning of this post. So open build settings check Unity C# project and click build, Unity will ask the location to create c# project create folder name App and click ok. It will take a while.
  • When build is complete, open Hololens101 solution in Visual Studio.
  • Change Solution Configuration to Release and CPU to x86, connect hololens to your machine and select device next to CPU selection if you don't have hololens download an emulator and hit play to see your first hololens app. It will take some time depending on your system. For more info on How to use Hololens Emulator?

  • Now your final demo will look something like this - I know my video making skills suck but this is the best I can do at 3:15 AM :D
If you are curious and want to know about this project, then leave a comment or email me .

Nipun David
Associate Lead - Programmer
4
Contributors
Preet Kamal Singh Minhas
Technical Architect - Programmer
Comments
Nipun David
2 months ago
Associate Lead - Programmer
Although at the time of writing this article I was using Unity5.6 but it will work the same way in 2017. In case any issue do leave a comment I will update the article.
0