A Pokemon-Go Clone for HoloLens

By October 30, 2016CodeProject, Hololens

I’m VERY excited about this article for two reasons:

  • It features one of the most cool demos I have ever demonstrated in this blog, and
  • it’s the first guest post, authored by a person I really admire and respect.

This article is written by Michail Moiropoulos, CTO of LightBuzz Inc., and was originally published on lightbuzz.com.

So, here we go…


As a developer, I am a big fan of Augmented Reality and its everyday applications in real-life. As a gamer, I love innovative games that provide new means of interaction and communication between the players. Pokemon Go has made a huge buzz in the casual gaming world. So, I decided to create an application that would provide this kind of experience using.

Video

This is the end result. Quite impressive, huh? Read on to find out how you can build such a holographic app in 5 steps.

Source Code

This project is open-source. You are free to modify the source code and even contribute to make it better! It’s hosted on GitHub.

Download the Source Code

Prerequisites

To run the Holographic application, you’ll either need a HoloLens device or a HoloLens simulator. Your development machine should meet the following hardware and software specifications:

LightBuzz has been one of the very first adopters of Microsoft’s HoloLens device. To help you get started, we have published the following articles:

Step-by-step tutorial

I suggest you have a look at the Unity introduction, so you have an idea about the process and the settings you’ll need to apply. Since we are all set, we can start by creating the Pokemon-Go clone project.

Step #0 – Create a new Unity Project

Launch the Holographic version of Unity and create a new project. You need the 3D capabilities of Unity. No need to add Asset packages for now.

Pokemon Go HoloLens - New Project

Step #1 – Populate the Scene

The Pokemon-Go game is simple: Pokemon are all around the place. You are holding a Pokeball in your hand. When you notice a Pokemon, you have to throw the Pokeball towards it to catch it! Read more about the game in the official website.

This is exactly what we are going to implement. So, open your empty Unity scene and populate it with 3D objects that represent Pokemon. You can put as many as you like. Just drag-and-drop them in the scene. Similarly, add a spherical object that will represent the Pokeball. For your convenience, you can use this cute kitten, created by Polydactyl, and this custom Pokeball, created by Angom Geetchandra (all included in the source code package).

Keep in mind that scene units represent actual distances in the real world. So, if your Pokemon have a distance of 1.0 unit, you are going to see them 1.0 meter ahead in the real world.

This is what my scene looks like:

HoloLens Pokemon Go - Scene

Of course, as Vangos Pterneas mentioned in our Getting Started with HoloLens article, do not forget to modify the Main Camera settings as follows:

  • Position → [0, 0, 0]
  • Clear Flags → Solid Color
  • Background → [0, 0, 0, 0] (or #00000000)

Pokemon Go HoloLens - Main Camera

Step #2 – Gesture Recognition

HoloLens is still an output device — similar to your screen (but more impressive). The same programming rules apply when building Mixed Reality apps. To add HoloLens-specific interaction, we have to use the HoloLens SDK for Unity. The SDK is included into the Unity installation; no need to download additional packages. Navigate to your project folder and create a new C# Script. Name it “PlayerInput.cs” and open it with Visual Studio or MonoDevelop.

To access the holographic features, import the following namespace:

using UnityEngine.VR.WSA.Input;

As you noticed in the video, we throw the Pokeball by doing a pointing gesture, known as Air-Tap. This is the most common gesture of HoloLens. It’s similar to the left click of mouse. Use that gesture whenever you need to select something in the 3D space.

Microsoft provides us with the handy GestureRecognizer class. The GestureRecognizer class encapsulates all the internal implementation of the finger gesture detection. Go on and create an instance of the GestureRecognizer class:

GestureRecognizer gestureRecognizer;

All we need to do afterwards is subscribe to the desired events. The GestureRecognizer can detect the Tap, Hold, and ManipulationTranslate gestures. This is how to subscribe to the events:

void Awake()
{
    gestureRecognizer = new GestureRecognizer();

    gestureRecognizer.SetRecognizableGestures(
			GestureSettings.Tap | 
			GestureSettings.Hold | 
			GestureSettings.ManipulationTranslate);

    gestureRecognizer.TappedEvent += Gr_TappedEvent;
    gestureRecognizer.HoldStartedEvent += Gr_HoldStartedEvent;
    gestureRecognizer.HoldCanceledEvent += Gr_HoldCanceledEvent;
    gestureRecognizer.HoldCompletedEvent += Gr_HoldCompletedEvent;

    gestureRecognizer.StartCapturingGestures();
}

Of course, do not forget to unsubscribe when the scene closes:

void OnDestroy()
{
    gestureRecognizer.TappedEvent -= Gr_TappedEvent;
    gestureRecognizer.HoldStartedEvent -= Gr_HoldStartedEvent;
    gestureRecognizer.HoldCanceledEvent -= Gr_HoldCanceledEvent;
    gestureRecognizer.HoldCompletedEvent -= Gr_HoldCompletedEvent;
}

Believe it or not, this is the magic of HoloLens. Microsoft has done a great job encapsulating all the information we need into familiar classes and events.

In our case, we are interested in the Tapped event handler:

private void Gr_TappedEvent(InteractionSourceKind source, int tapCount, Ray headRay)
{
    // Air-Tap detected!
}

 

View the complete script

Step #3 – Add interaction between the 3D objects

It’s now time to add some bits of interaction between our Pokeball and Pokemon objects. Create two new scripts, named Pokeball.cs and Pokemon.cs. Assign the first one to the Pokeball object and the second one to every Pokemon object.

The Pokeball.cs script determines how the model of the Pokeball will move in the 3D space. Since I want to keep this tutorial as simple as possible (and focus on HoloLens), you can see how the properties and members of these classes by checking the source code.

What matters most is the Throw() method. The Throw() method applies the required velocity and direction to the 3D object:

public void Throw(Vector3 velocity, Vector3 angularVelocity)
{
    transform.parent = null;
    rigidbody.isKinematic = false;
    rigidbody.velocity = velocity;
    rigidbody.angularVelocity = angularVelocity;
}

The velocity and anglularVelocity parameters are provided at runtime. These parameters can be modified to make the game harder or easier.

The Pokemon.cs script contains the collision-handling information for our monsters:

public void Capture(Transform pokeball)
{
    GetComponent<Collider>().enabled = false;

    StartCoroutine(Coroutine_Capture(pokeball));
}

IEnumerator Coroutine_Capture(Transform pokeball)
{
    CanBeCaptured = false;

    float delta = 0;

    while (delta < 1f)
    {
        delta = Mathf.Min(1f, delta + Time.deltaTime * MOVE_TO_POKEBALL_SPEED);

        transform.position = Vector3.Lerp(initialPosition, pokeball.position, delta);
        transform.localScale = new Vector3(1f - delta, 1f - delta, 1f - delta);

        yield return null;
    }

    CanBeCaptured = true;
}

Finally, get back to the PlayerInput.cs script and add a call to the Throw() method:

private void Gr_TappedEvent(InteractionSourceKind source, int tapCount, Ray headRay)
{
    var cameraRotation = Camera.main.transform.rotation;
    var randomThrowForce = Vector3.Lerp(throwForceLeft, throwForceRight, Random.Range(0f, 1f));
    var randomThrowAngularForce = new Vector3(Random.Range(0f, 50f), Random.Range(-2f, 2f), Random.Range(-1f, 1f));

    pokeball.Throw(cameraRotation * randomThrowForce, randomThrowAngularForce);
}

The parameters named throwForceLeft and throwForceRight have the following default values:

public Vector3 throwForceLeft = new Vector3(-1, 4, 3.5f);
public Vector3 throwForceRight = new Vector3(1, 4, 3.5f);

Feel free to modify them and experiment with different values.

View the complete scripts

Step #4 – Deploy for UWP

We are almost there! We can preview our app using the Unity Editor, but we need to deploy it for the Universal Windows Platform (UWP) to test it in an actual HoloLens device (or simulator).

Click File → Build Settings and select the following:

  • Windows Store
    • Universl 10
    • D3D
    • Local Machine
  • Player Settings → Publishing Settings
    • Spatial Perception
    • Internet Client
    • Microphone

Pokemon Go HoloLens - Build Settings

Click Build and wait until Unity creates a Visual Studio Solution project. When done, open the .sln file to launch Visual Studio.

Step #5 – Run!

Visual Studio has packed the binaries and created a project bundle you can later submit to the Windows Store. To run your app, you need to modify the following parameters from the primary command bar:

  • Release
  • x86
  • Hololens Emulator or HoloLens Device

HoloLens Visual Studio - Command Bar

Hit the green Run button to deploy the application! This is the end result of our game:

Pokemon Go HoloLens Air-Tap

Disclaimer: we do not have any official connection to the Pokemon company. We are just huge fans of their games since our childhood! The 3D models used are not actual Pokemon; they are offered for free from their creators.

Summary

In this tutorial, you’ve learnt how to use HoloLens with Unity3D and recognize the most common gestures.

‘Til the next time, enjoy the new Augmented Reality World!

By the way, do you need Digital Reality experts for your next cutting-edge project?

Contact our Team

Author Vangos Pterneas

Vangos Pterneas is an award-winning Microsoft Most Valuable Professional. He is helping companies from all over the world grow their revenue by creating profitable software products. He loves Motion Technology and Mixed Reality. Vangos is the CEO of LightBuzz Inc and author of The Dark Art Of Freelancing.

More posts by Vangos Pterneas

Leave a Reply