how to unity vr webxr web

How to get started with WebXR in Unity

WebXR is a technology with enormous potential, but at the moment it offers far worse tools to develop for it than standalone VR, where we all use Unity and Unreal Engine.

Mozilla, that is doing a lot for the immersive web, has so decided to develop a WebXR exporter for Unity, to let all Unity developers create WebXR experiences with the tool they already know well. This project dates from 2 years ago, but recently the WebXR plugin has been improved and updated.

As a Unity developer, I think that it is a very important enabling solution. Yes, there are some bugs, and the resulting code is not much modifiable (like it happens with A-frame instead), but finally, I can create WebXR experiences very easily, with the tools that I use every day.

I’ve spent the last days giving this pluging a try, so let me show you how to create your first WebXR experience inside Unity!

How to get started with WebXR in Unity – Video Tutorial

I made a very complete Video Tutorial showing you step by step how to create your first cube in WebXR inside Unity. I go from the requirements to the final deploying of the project. I think this video is a very good guide to begin your journey inside WebVR development, so watch it now!

How to get started with WebXR in Unity – Textual Tutorial

Ok, let’s dig into Unity WebXR development!

Requirements

First of all, be sure to have all the tools required to follow this tutorial. You’ll need:

  • Unity game engine (of course). If you download the WebXR plugin from its GitHub page, you can have Unity 2018 LTS (2018.4.20), while if you get it from Unity Asset Store, you must have at least Unity 2019.3.4. I downloaded Unity 2019.3.11 for this project. Be sure that your Unity installation has WebGL support installed, otherwise use Unity Hub to add it;
Unity must have WebGL Build Support (Image by Mozilla)
  • A web server, with SSL certificates. This may be a local server on your pc (Apache, IIS), a server on a local virtual machine, or a web server that you own. From my experience, launching the WebXR page on your disk opening it with your browser doesn’t work for security reasons, so you had better have a server. How to do that is not the purpose of this tutorial, but I can advise you to use your webspace if you have one (e.g. I have the one of this blog), or use Glitch, or install a LAMP/WAMP server on your machine (in this case, don’t forget the SSL certificates).

How to set up the environment

Open Unity, and create a new project. When prompted what kind of project to create, select Universal Rendering Pipeline (URP) or Lightweight Rendering Pipeline (LWRP), depending on your Unity version. This is not a mandatory step for WebXR, but it is the format chosen by Mozilla for its demo, so we’ll stick with it.

After the project has been created, go to the Asset Store tab and look for WebXR Exporter. You’ll find a plugin by Mozilla. Click on it and import it into your project.

mozilla webxr exporter unity
This is the plugin you have to add to your project

UPDATE (2021.12.24): My friends from Crazy Kung Fu suggest that you now use the Package Manager to get the package, because on the Asset Store it is not updated

Select File->Build Settings…->Player Settings, being sure that the platform selected is still PC, Mac&Linux Standalone. In the settings window that will pop up, go to the XR Settings group item and click on “Virtual Reality supported”. This will make sure that we can correctly preview the content inside Unity.

unity webxr

To adjust also the input inside the editor, you have to substitute the content of the file <Project_root_dir>/ProjectSettings/InputManager.asset with the ones provided by Mozilla: https://raw.githubusercontent.com/MozillaReality/unity-webxr-export/master/ProjectSettings/InputManager.asset. Remember that you must do this operation outside Unity, because the Project Settings are outside the Assets folder. You can use File Explorer to substitute the whole file, or Notepad++ to substitute its contents.

Now you can return to the File->Build Settings… dialog and select the platform WebGL, then hit “Switch Platform” and let Unity switch to WebGL mode.

unity webgl vr
This is the platform you have to build for

The last step is to return to the Player Settings, and now go to the “Resolution And Presentation” options group. In the section “WebGL Template”, select WebXR. Then add a “Description” and a “Name” of your app as you prefer.

WebXR template
This is fundamental: select the correct WebGL template

We are all set and we can start developing!

Plugin Analysis

The Plugin adds the WebGL and WebXR folders to the project. The exporter basically creates a special type of WebGL application that supports virtual reality, that’s why there are both directories.

The most interesting code is inside the WebXR folder:

  • The Config folder contains some scriptable objects with inside the mapping between Unity Input and the VR actions. Mozilla already provides two samples, but we are free to customize the input received by the application as we wish;
  • Models contains the models used for both hands, plus their animations. Notice that Mozilla already provided one simple hand model plus a basic “grip” animation, but you’re free to use the hand model that you want;
  • Prefabs owns the main prefab used by WebXR applications, the one of the WebVR camera (more on this later on);
  • Samples contains the Desert scene, from which you can learn how to perform some basic interactions with objects (I advise you to give it a look);

The WebXRCameraSet prefab contained in Prefabs folder is the most important thing that you will use. It is a barebone prefab letting you have your head and hands in VR, but you can start from there and customize everything as you want. You can see that every hand has an associated Animator and RigidBody, and its children objects are the model and the bones of the hand. You can substitute the models, you can add new hands animations, and everything would still work. Notice that the default prefab DOES NOT TRIGGER ANY ANIMATION associated with your fingers movements, but you have to script all by yourself (more on this later in the tutorial).

The WebXRController script associated with each hand is the one that you can query to obtain the status of that hand, and it gets an InputMap parameter through which you can decide how to map standard Unity input to VR input (more details at this page).

Let’s play!

To have a taste of WebXR, you can try the demo scene, located at Assets\WebXR\Samples\Desert. The scene is called “WebXR”.

If you open it, you see exactly the same scene advertised on Mozilla’s website. You can put on your headset, press the play button in Unity, and if everything is configured correctly, you would see everything in VR. You can take the cubes and the spheres that are close to you and interact with them. You could also build it and enjoy this VR world.

Make some mayhem with cubes! (Image by Mozilla)

But we don’t like this fancy scene… we like gray cubes, isn’t it? So follow me, and I’ll let you create some beautiful WebVR gray cubes!

Your first WebXR experience in Unity

Create a new scene in your folder Assets\Scenes and call it GrayCube. If you don’t know how to create something in Unity, start by clicking the right button of the mouse in the Project Tab.

When you’re done, open the GrayCube scene and as a first thing, remove the Main Camera. Take the prefab WebXRCameraSet from the Assets\WebXR\Prefabs folder and put it into the scene. Basically, we’ve substituted the standard camera with the VR camera. Notice that you don’t have to raise this camera from the origin since the camera will automatically go to the right height when the program gets executed (look at the script WebXRManager).

Now it’s time to add the cube. In the Hierarchy Tab, click with the right button of the mouse and select 3D Object -> Cube. Now move the cube where you want using its 3D arrows inside the Scene Tab.

And it’s over! Easy peasy! You’ve done your first WebXR experience in Unity! Save the scene, press the Play button and you can see the whole scene and your hands inside your headset :O

Your first interactive WebXR experience in Unity

We all love seeing gray cubes in Unity, and this is what I love to do as tutorials (like for instance in this tutorial on how to get started with Oculus Quest in Unity). But the problem of this experience is that it is probably too much static, and even your hands don’t perform any kind of animation.

As I explained before, the prefab offered by Mozilla gives you just very basic functionalities, with the possibility of expanding it as you want. Let’s take inspiration from the example and add some interactions.

So, let’s make the hands open and close. Go back to the Project Tab and create a new C# Script in Assets\Scripts and call it CloseHands.cs. Add it to both the WebXRCameraSet\handL and WebXRCameraSet\handR gameobjects in the scene, by dragging it onto them.

Now open the script in Visual Studio by double clicking on it and substitute its code with this one

The code is fairly simple: we get the Animator associated with the hand and also its WebXRController behaviour. Every frame, we query the WebXRController for the status of the buttons, and we use the Animator to change the shape of the hand depending on this. The animation that the Animator uses by default is a simple “close hand” animation provided by Mozilla, and the system shows a particular frame of that animation depending on the status of the buttons. The more you press your Grip button, the more the hand closes. If you press the Trigger button, the hand closes completely instead.

That’s it. Press Play, and now you can see that you can close your hands using the buttons in your controllers!

Let’s go deeper

Let’s add another simple functionality that colors the cube!

Back to the Project tab, create a new script in the Scripts folder and call it ColorCube.cs . Then add it to your left hand by dragging it onto the WebXRCameraSet\handL gameobject in the Hierarchy. The code of the script should be this one:

What we do in this script is: if the WebXRController detects that you’ve pressed the Trigger, it looks for the Cube in the scene, and substitute the main color of its main material with a random color. Expert Unity developers probably would comment that using GameObject.Find() every time is a bad practice, but here we’re just making a sample, so it’s ok for the sake of simplicity. If you wonder why I don’t use material.color, it is because we are in URP and there is no “_MainColor” in the standard Lit material.

Save everything, press Play and now you can see that as soon as you press the trigger button of your Left hand, the cube changes color!

The problem is that if you keep the button pressed, it keeps changing the color every frame, creating a discotheque effect. If you want that for every time you press the trigger, the color changes only once, the code should be this one:

It is identical to before, we’ve just used GetButtonDown instead of GetButton.

Press Play and you should see that everything is fixed now. You can close both your hands and when you press the trigger button on your left hand, the cube changes color in the right way!

(While doing my tests, I’ve noticed that sometimes the GetButtonDown method gets stuck and works only once. This looks like a bug of the plugin, and I hope it will be fixed soon).

Deploy your game

Now that you’ve created this killer app, it’s time to deploy it. So head to File-> Build Settings… , remove the default scene in the “Scenes To Build” list and add the current one by using the Add Open Scenes button. After that, press the Build button. Select where the project must be built and then go watching some panda videos on Youtube, since WebXR builds can take a lot of time. Notice that Mozilla advises using “Build and Run” so that you can test your application on the fly without messing with web servers, but it has never worked for me. For this reason, I advise you to use this alternate approach.

Who doesn’t love fluffy pandas? You can watch this video while you wait for your build to finish

When the build has finished, you have a folder containing your WebXR experience, with an index.html file and a lot of other stuff. Take this folder and put it inside your web server (local or online).

After that, try to access it by simply going to the web address of your just built index.html file with your browser. But remember that:

  • You must use a WebXR-compatible browser (Chrome and Firefox are ok, Edge should be as well);
  • If you don’t have a web server and try to just access the index.html file on your hard drive with a browser, security restrictions will prevent your app from working;
  • If you access your webpage using http and not https, it won’t work. Force the use of https by typing https:// in your URL;
  • If when you’re prompted by Firefox if you want to allow VR on that page, you don’t click on “Allow” in time, it won’t work. My advice is to click on “Remember my choice” and then on Allow in the authorization popup, then reload the page. This way you are sure that every time you load your experience, VR will always be enabled since the beginning.
firefox vr permission
Enable VR permissions for your page permanently, then refresh. This is the safest approach to make your web page to work

If you don’t see any popup saying that you’ve not a VR headset or a VR compatible browser, everything is ok.

webxr not working firefox
If you see this popup, then you’ve made something wrong. Try again

Click on the Headset icon in the bottom-right corner of your browser and BAM! You’re in WebXR!

Test the interactions, and you see that you’re able to move your hands and make the color of the cube to change. You did it!

Further references

Now it’s your turn to unleash the power of Unity to create Web experiences!

You can examine the Desert sample to learn how to implement basic interactions with objects, or you can examine the source code of the plugin, plus its complete documentation, at its official page: https://github.com/MozillaReality/unity-webxr-export


I hope you enjoyed this tutorial, and if it is the case, send me many hugs, subscribe to my newsletter to not miss my future posts, and donate on Patreon to support my hard work!

(Header image by Mozilla Foundation)


Disclaimer: this blog contains advertisement and affiliate links to sustain itself. If you click on an affiliate link, I'll be very happy because I'll earn a small commission on your purchase. You can find my boring full disclosure here.

Releated

We need camera access to unleash the full potential of Mixed Reality

These days I’m carrying on some experiments with XR and other technologies. I had some wonderful ideas of Mixed Reality applications I would like to prototype, but most of them are impossible to do in this moment because of a decision that almost all VR/MR headset manufacturers have taken: preventing developers from accessing camera data. […]

quest 3s leak

The XR Week Peek (2024.03.19): Quest 3S and Pico 4S leaked, and much more!

Today is Father’s Day in Italy, so I want to send a big hug to all the fathers out there, wherever they may be.  Life is busy these days, but in April I will have more time to collaborate with you all. For this reason, I’ve given a refresh to the pages where I talk about […]