Create Virtual Tour App in Unity with Hotspots in VR


In this tutorial, we’ll be learning to create panoramas and hotspots to create a virtual tour app in VR using Unity. Hotspots are regions on a photosphere that users can interact with. Each hotspot is associated with a panorama in this case.

Specifically, you’ll learn how to:

  • Import panoramas as cubemaps & creating multiple cubemaps.
  • Adding hotspots to these cubemaps & interacting with them.
  • Teleporting to different pano’s using these hotspots.

Getting started to create virtual tour app in Unity

I’m using Unity 5.6 for this tutorial with a Galaxy S7 Edge for the Gear VR. But the project itself should run on almost any VR platform given that the project is setup for the target platform. You need to setup Gear VR for Unity development first.

Now let’s begin. Create a scene in Unity by File > New Scene > Name it “Main”.

new scene unity

Panoramas and Cubemaps in Unity

Cubemap

Cubemap texturing is a form of texture mapping that uses a 3D direction vector (a fancy phrase that means nothing more than a direction) to index into a texture that is six square 2D textures arranged like the faces of a cube.  Again consider the environment around you now.  You can “capture” a 360-degree view of your surroundings by standing in one place and taking six photographs each at an orthogonal 90-degree view from the others

These cubemaps provide a simple method of environment mapping, in which distant scenery – such as skies and surrounding environments – is mapped to a panoramic texture(A texture is a surface or an object. in this case a panorama image). Under the hood, these textures are stored as a series of six images mapped to the inside faces of a cube.

Panorama

Hence we map our panorama texture to a cubemap. To do this we need to import our texture as a cubemap. Any file you copy into your Project’s Assets directory is a Unity Asset. And the properties of these assets can be changed in their import settings. You can learn more about how Unity handles cubemaps here.

Creating panoramas & cubemaps

panorama import unity

Copy the desired panorama into your @ProjectDir/Assets/ directory and select them to view their import settings in the inspector. Set the Texture Shape to Cube and hit apply. Unity will re-import the image and change it into a cubemap which we can use. You can find some demo panoramas here if you need them.

To view this panorama we set it as the Skybox in Unity. Skyboxes are a wrapper around your entire scene that shows what the world looks like beyond your geometry. They are rendered around the whole scene in order to give the impression of complex scenery at the horizon. Internally skyboxes are rendered after all opaque objects, and the mesh used to render them is either a box with six textures or a tessellated sphere or a Cubemap which we will be using.

To implement a Skybox create a skybox material. Go to Project View and create a folder called materials. It is usually advised to have assets of similar type in a base folder. You can use this structure as a starting point.

Each folder serves as home base for specific assets:

  • Materials: Materials used for the scene including the blue bouncy balls
  • Models: All the models
  • Prefabs: Loose object prefabs
  • Scenes: The game scene is in here
  • Scripts: All the scripts
  • Textures: The single texture shared by all objects in the scene

Now in our Materials folder. Create a Material by right clicking and Create > Material. Name it to Skybox.

creating material unity

Select the Material and change its Shader by selecting the dropdown > Skybox/Cubemap.

material skybox shader unity

Our Skybox Material is ready.Let us add it to the scene by using the Window >Lighting menu item and specifying your skybox material as the Skybox on the Scene tab. Select your created Material by assigning it under Environment > Skybox Material > Skybox(our material name).

lighting settings unity

setting skybox unity

We’ve set our created Material as our scene’s skybox. If you notice the whole skybox in the scene is grey. That’s because we haven’t assigned any cubemap texture to our material. The texture that we imported as a cube can now be set to our Material. Select the Cubemap part of our “Skybox” material and assign our texture. You can see the changes in the scene view immediately.

assign skybox unity

Creating panorama environments for our virtual tour app

To create our virtual tour app we won’t be using these cubemaps as a global skybox but will create individual sphere’s with the cubemaps so that we can switch between different ones. The reason we do this is that although we can use skybox and switch cubemaps with that, we need to place hotspots in a relative position to the panoramas which cannot be achieved if we use a skybox. These individual spheres will work as separate environments and we switch between different spheres based on the hotspots inside each one of them.

To create our panorama cubemap sphere, in the Hierarchy > Create> 3D Object > Sphere. Set its Scale  to (10,10,10) & Position to Origin & Name it to Hall Sphere.

creating sphere with unity

As we create a material with a Skybox or CubeMap shader for our skybox we create a separate material with the same properties for each of our panorama cubeMap sphere. Here we going to create one for the Hall Panorama, from these demo images previously linked. Under Materials folder in Project View > right click > Create Material > name it to “Hall”. Under its shader dropdown select > Skybox > Cubemap. Assign the Cubemap component of the material to the Hall Panorama Image Texture imported as a cube in its import settings as described before.

skybox material unity panorama

 

Now we assign this material to our sphere by dragging and assigning it to the Materials component of the Sphere’s Mesh Renderer. You can see the panorama wrap around the Sphere. Simple as that!


a

Now we need to create more of these spheres depending on how many panoramas we need. I’ve used three in this demo. And we’ll be creating our hotspot Objects inside these sphere objects.

panoramas unity

 

Creating Hotspots

The Flow for our Virtual Tour will be like this. We have 3 Panoramas – Hall, Kitchen and Dining Table. These paths are possible.

  • Hall -> Dining Table.
  • Dining Table -> Kitchen, Dining Table -> Hall.
  • Kitchen -> Dining Table.

Since we’re dealing with sphere’s we can place the hotspots in a relative position to the center of our panorama sphere, because that’s where the camera will be. These hotspots are just sphere game objects.

For the Hall panorama, Select the Hall Sphere, then GameObject > right click > 3D Object > Sphere. Change its scale to (0.5, 0.5, 0.5) to make it smaller. This adds a sphere gameobject as a child object to our Hall SphereSince we can go to Dining Table panorama from here name the small sphere to Dining Table Hotspot. Set its Position to (-0.31, 0, -0.31) & Rotation to (0,44,0) so that it looks like it’s on top of our dining table when we look from the center of our Hall Sphere.

hotspots unity vr

Now we need to add behavior to the hotspots so that when we tap on them we are teleported to panorama associated with that view as a Virtual Tour. We need to get our hands dirty with some code for that.

Create a Global Manager Empty GameObject in our scene. Add a script to it in the Inspector > Add Component > Type Name of the script TourManager > New script. It’ll compile and create the script. Open the script by double clicking on it.

We use this class with static delegates to set the position of our camera by calling them from their respective behaviors. Save the script and assign the Main Camera, in this case, our OVRCameraRig gameobject to the Camera property of the script.

ovrcamera unity

 

Now let’s add behavior to the hotspots. Navigate to the Hotspot Gameobject in the Hierarchy and add a new c# script named Hotspot.cs to it in the Inspector Window.

In this behavior, we handle pointer event in VR. You can learn about that in another article at depth here. But basically, we are handling callbacks for PointerClick, Enter, and Exit events and call our methods accordingly.

In the Inspector we assign the Current Panorama Sphere gameobject to the ThisPanorama property and the Target Panorama Sphere gameobject to the TargetPanorama property.

In SetSkyBox() we call the TourManager.SetCameraPosition delegate and pass in the Target Panoramas position so that the camera can be set to that position. Since we’re using Skybox shaders for our sphere it is drawn on top of other similar material shaders in our scene. To fix that we disable and enable the Panorama Sphere’s using the SetActive() call.

In the OnPointerEnter andOnPointerExit callbacks we increase & decrease the scale of the hotspot so it grows on hovering and goes back to normal on exit. In OnClick we call the SetSkyBox() method.

hotspots script unity

Repeat the same for other hotspots as well, assigning their Panorama Sphere to the ThisPanorama property and Panorama Sphere you want to transition to from the hotspot to the TargetPanorama property.

That’s it our setup for vitual tour app in Unity is ready!

Building to a device

Since this if for VR we need to enable its support by going to Edit > Project Settings > Player. In the Window enable Virtual Reality Supported. Add or Remove SDK’s depending on what the target platform is and perform pre-build requirements.

player settings unity

Once all this is setup, press Ctrl+Shift+B (Win) or CMD+Shift+B (Mac) to bring up the Build Settings Windows. Click on Add Open Scenes to add the current scene to the Build.

build settings unity

 

Click on Build & Run to test on your device!

Virtual tour app in VR using panorama’s result

 

11 responses to “Create Virtual Tour App in Unity with Hotspots in VR”

  1. Shyam says:

    Hi Kaushik,
    I think you have missed some part. I am unable to render camera inside 360 cubemap. I also didn’t get how to setup OVRcameraRig and OVRPointerRing components in Hierarchy window. Can you please help me out.

  2. Mimmo Oggiano says:

    Hi Kaushik, i’m a newby and for this I follow all your tutorials mentioned in here. As Shyam my camera is unable to render cubemap from interior of the sphere. I try to use a planar map for the shader using a script to made the texture visible from interior and it works. I’m not sure if this can interfere with the rest of the tutorial. Unfortunately the pointer interaction with hotspot doesn’t work for me. All the Oculus libraries and adds-on have been imported in the project. The apk is compiled correctly. I began with firs tut called “create a gaze based ui for Gear VR in Unity. Then I continued with virtual tour app tut. Thanks in advance for Your help.

    • Kaushik says:

      Hi Mimmo Oggiano,

      For the interior to be rendered only thing need to be done is to set the material’s shader to Skybox/Cubemap. I’m sorry to know that you’re having problems with the Gaze.

      I’ve uploaded the entire source of the project to Github. Here’s the link : https://goo.gl/g14YYt

      If you need further help with the pointer, please let me know precisely what the issue is.

      Thanks.

      • Mimmo Oggiano says:

        Thank You for the Project link. I downloaded it and of course it works. Maybe the problem with my exercise about Your tutorial is caused by newest release of Oculus Utilities. Is it normal to see all the spheres from the OVRCamera as reflecting crystal material?
        My goal is to apply stereo images starting from your tutorial. Thanks in advance.

  3. Amrit Aryal says:

    Hi Kaushik ,

    While building the project the inner sphere only rotate , since you are using Dotween plugin , can u help me on some detail of this plugin in this project because after completing everything, i didnt get output, i’m not getting camera inside sphere 1 in your case Hall . it is outside the sphere in centre to scene , i have followed gazed base ui tut but not getting output as seen in above video . And also gaze pointer is missing in the scene am i missing something ??

    Thanks in Advance u are doing great :).

    • Kaushik says:

      Hi Amrit Aryal,

      Apologies for the late reply. In order to have our Camera centred, the camera and the first sphere’s transform should be at the origin. Let me know how it goes.

      As for your other query i have uploaded the entire project’s source to GitHub. Please take a look at it for a much clearer explanation. Here’s the link : https://goo.gl/g14YYt

      If there’s anything else you need help with, you can email me. Willl be glad to assist.

      Thanks.

  4. David Cahill says:

    Great Tutorial works a treat, newbie to unity here but how do I make it so when a new scene loads it starts off say pointing north and not the direction you are looking.
    Thanks

    • Kaushik says:

      Hi,

      You can do that by changing the “y” value of the “Rotation” Property of the “Transform” Component of the OVRCameraRig.

  5. Kaushik says:

    Hi,

    Do you have this issue in the Editor or when running on your device?

    • Mimmo Oggiano says:

      I have this issue in playing game in Unity and running the app on my GearVR. Is not present in Unity editor. I solved the issue setting camera clipping range in OVRCameraRig. This value range is greather than single sphere radius but small of the distance between first sphere center and second sphere surface. In this mode other spheres are not included in the visual range of the camera. Finally, using Your project as template, I made a full stereo virtual tour with multiple hotspot and no errors for now. Thank You very much.

Leave a Reply

Send Lesson #1
Join 1000s of VR Developers

Build your Career in VR with this 6 part FREE course

Send Lesson #1
close-link
Add Me To VIP
Join 1000s of VR Developers

Build your Career in VR with this 6 part FREE course

Send Lesson #1
close-link
We've launched a WebVR Course with 25+ projects with source code! Check it out.
Get The Course
close-image