Introduction to WebXR with Babylon.js


In this workshop, we'll introduce you to the core concepts of building Mixed Reality experiences with WebXR and Balon.js.

You'll learn the following:

- How to add 3D mesh objects and buttons to a scene

- How to use procedural textures

- How to add actions to objects

- How to take advantage of the default Cross Reality (XR) experience

- How to add physics to a scene

For the first project in this workshop, you'll create an interactive Mixed Reality experience that'll display basketball player stats to fans and coaches. For the second project in this workshop, you'll create a voice activated WebXR app using Balon.js and Azure Speech-to-Text. You'll then deploy the web app using Static Website Hosting provided Azure Blob Storage.


Hello, everyone. Welcome to the WebXR and Babylon.js workshop. My name is Gustavo Corbira. I'll be your presenter today. And I'll give you a little bit of background of what WebXR and Babylon.js in just a minute. But in case you haven't been able to see, we'll be requiring to have Visual Studio Code installed and node.js installed for this workshop. And I pasted a message in the chat already including the links to download those in case you don't have them. I'll just post the place it again just in case. As I said, my name is Gustavo Corbira. I am a cloud Advocate for Spatial Computing at Microsoft. I've been working here for a little longer than a year now. And my job basically encompasses providing developers access to content that will hopefully help them and support them in their learning journeys when it comes to spatial computing. That is extended realities, mixed reality, augmented reality and virtual reality. Today, we're going to be focusing on two aspects of mixed reality, WebXR experiences, which will provide you with the necessary understanding for mixed reality development as well. The workshop will be split into modules. Between them I'll give a little bit of a 10 to 15 minute break for all of you to catch up, stretch your legs and so on. And we'll be both in both of them will be using Babylon.js as the basic framework for this. So, before we start, the first module we're going to be working on, it's one that we developed in partnership with Warner Brothers during their Space Jam during the latest Space Jam movie release. So, it's going to be themed around that. It's going to be kind of funny. It's going to feel like you're working with things that you probably worked with as a kid again. And we're going to be creating a Babylon.js application for this. So, as a little introduction as to what WebXR is, WebXR is a technology that you can use to create virtual reality and augmented reality experiences in a browser by taking advantage of webgl. webgl basically allows the browser to use our computer's GPU and enables us to build three-dimensional experiences. Some of these cross reality applications are specific to a device or a platform. But WebXR is not, given that it's working through the web through the browser. So, the content that we create in WebXR is actually cross platform and can work on multiple devices as well. And all we need to do to create a WebXR app is basically a javascript with a little html and css included into it. So, you'll see this as we start building our project in this unit. Now, there are multiple WebXR frameworks available. The one we're going to be using today is called Babylon.js. And this is basically a complete javascript framework that allows us to build three-dimensional games and experiences with HTML5, webgl, WebVR, and WebAudio. And it now has Babylon Native, which actually lets us bring these experiences a little beyond the browser. The ability for us to use javascript to create a three-dimensional experience makes building the new metaverse world even more accessible to all types of developers. And it's actually a great way to start building and learning the whole realm of extended realities through the web. Thankfully, now Babylon.js has something called the Babylon.js Playground, which allows us to try out our creations in the browser without having to download anything. So, this is something I highly recommend for anyone that wants to try out Babylon.js after the workshop. As you can honestly just build everything on the web, test everything on the web. And if you want to download or save your project, you can. I'll leave a link to the Babylon.js Playground in the chat so that y'all can save it if you want to use it in the future. So today we're going to be building a scene to display some of the players on the Space Gem movie. And we're going to be displaying an icon for each one of the characters, an efficiency rating that's going to be predetermined, and basically build it in a way that you can interact with it in either VR or AR, depending on where you want to build it. So the first thing we're going to be doing is setting up our developing environment. So for this, we're going to be creating a plain Babylon.js experience so we can start from zero. But we're going to be using a GitHub template, given that some of the assets that we want to have should be easier to get through a repo. So once we get into the link that I just shared, you should be prompted onto a page similar to this, which is creating a new repository from the given template. Basically, just give any name that you want your repository. In this case, I'm just going to give it... And make sure to include all branches when creating this repository from template. So this is basically all you have to do is just click on the green button here, and it'll generate your repository. And from there, that's the first step that we're going to go through. Now that we have the repository set up, our next step is to clone this repository. I'm sure most of you are experienced developers, you know how to do this through the terminal. I'm going to be doing it directly through Visual Studio Code, given that I want to be working on this environment from now. So basically, what you can do in Visual Studio Code is just call for the command palette, which is going to be just control plus shift and P. And here we can just write git clone. And since we want to clone from GitHub, I should have copied the repository's address first. So you can just go to code, copy the cloning URL here, and paste it into Visual Studio Code, and that should clone it without an issue. Just select your folder you want to import it to. And just click on open once this opens up down here. So this should give us the general repository in our computer, our local computer. Now first thing I want to do here is to open our terminal in VS Code. So I'm just going to open a new terminal. And we want to run the starter projects just so that we can see how it looks. So first thing we're going to do is write down npm install so that we can install all the packages that are included in the repository that we just cloned. And once this is done, we're going to be doing a run build so we can check it out, check how this is going to be looking like at the moment. All right. So now that everything has been installed, we do npm run build. We can run our current iteration. It's going to wait until it finishes running. Then we're going to do an npm start, and we're going to check it out on our local host. All right. It's been started. We can just do npm start. Now that's been compiled, we should be able to go to our browser and go directly into local host. And we should be seeing something like this. This is our starting Babylon.js environment. So this is going to be our starting scene. Just a simple sphere. All right. So now we're going to get started to actually building some things here. So we go back to our Visual Studio code. We can close this. We can do control and C and terminate the current job so we don't have it running while we're working on this. So we're going to start by looking at the different things we have in our repository. So the first thing we have is going to be our do we have an html and css file? It should be here in source. So we have our html file. Basically we don't have to do anything with it. But it's good to give it a look to see where we're starting. So we have a rendered canvas and basically our script is included in our index.js. The only thing that we need to make sure is that we have an inline style in here. Because that's the minimal css that we will need. And the only html that we really need is just the canvas element and the script tag to it. The next thing we want to look into is our index.ts file. This is basically the typescript file that's going to create the main scene. Babylon can be run in both typescript and javascript. We're going to be going over the typescript version this time. And basically what this is doing is it wants to run the npm run build. This is sent out into javascript and saved to the distant folder. And then the file is then called with the script tag and the index html part. In this case we're using webpack, which is an open source javascript module bundler. And it will generate this static assets that represent the modules that we're building. And the configuration for this webpack, it's in the webpack config file. And this describes just how to bundle the assets in this folder. It's not something we need to take too much attention into. So, the now the code that we see here is basically a general code for Babylon. But basically it's how we import the needed packages from Babylon to create our game scene. And they create the Canvas, grab render Canvas from the html tag and from the html then to the body section. This basically just creates the engine variable pass into the Babylon engine. And then we can when we run it, we can see what's happening in our general part. That's basically the first part I want to work with here. All right. So, the first thing I want to do is create a scene. Basically we can create a scene. You can see here like I'm just comparing here with here. Just one second. Something's not going alongside the documentation that we have. Okay. So, I'm going to All right. So, what we're going to be doing is basically I'm just going to clear out this index.ts file and we're going to be adding our own code into it. I should have imported it differently but that's fine. So, the first thing I want to add is our imports. I'll just save it somewhere else just in case. All right. So, the first thing I want to do is import this into our index.ts. So, we're going to import. Basically it's going to be telling all the native packages that we need to import from Babylon.js. So, in this case we're going to be importing the scene. So, I'm going to import the scene. So, I'm going to import the scene. So, I'm going to import the scene. All these found. All. Let me see if I can give you all a little bit of zoom here. Also import. And we're going to declare our canvas. That's the first thing I want to look in here. Render canvas. We're just going to declare basic variables for the engine. So, it's going to be our variable as well. All right. This should be enough for now for our initial index.ts. Save it for now. Should be getting some errors at this time, but that's fine. We're still not moving forward completely from here. And now we're going to be creating our scene. So, basically the scene is what you see on Babylon.js. It's going to be the main thing that we're showing. So, beforehand what we're seeing with a sphere in the center, that's the scene that we're working on. And we're going to be doing this by using the create scene function. Which is what's going to be initializing the scene. It passes the engine and creates a camera. Camera is basically the element that allows us to see what's in the scene. It's a point of view of the game player in this sense. So, for that, we're going to be... So, that's the synchronous function. Basically create a scene function. I'm going to scene variable. Camera. And for this, we're going to be using basically how we want it to rotate. And this is going to be done by the alpha and beta numbers. This is something we don't worry too much about. I'm just going to use values that I have from earlier. And we're going to have 3. And the current scene. We want to make sure that we set up how the camera is going to be able to rotate based on the wheel that we have. So, we don't want it to rotate like crazy. So, for this, we're just going to add a percentage of 0.01. Just going to make sure that it doesn't rotate too much when we're trying to go around it. And we want to attach the control of the camera to our canvas. So, it doesn't move freely. And the next thing we need to create is add the light. Basically add is that it's the cool thing about our virtual reality is that it's a blank state. We want to build anything on top of that. And there won't be any light until we add it. So, basically if you try to run it without a light, it's just going to look like a completely pitch black screen. So, to this, we just create a new light. Which is what we imported from Babylon earlier. This might be a new vector3 coordinates. Let's see. Now, once the light is created, we want to make sure we have some intensity to it. So, it's not too crazy. Just going to add 0.7. These are values that you're free to play with. These are values that I tested before. But depending on what you're working on, these values might change. If you increase the intensity of the light, it can be too overwhelming to look at or too bright. You want to make sure you have a normal value in there. The next thing that we want to do is basically create our environment. Create our default environment. This is something that we can use a specific function from Babylon.js to get the basics for that environment. We don't have to build it out completely. So, for that, we're just going to create a constant environment. Scene.create. I'll just bring the basics that we need. And then we're going to create the default XR experience. This provides basically our basic experience helper, initializes it. It creates an html UI button to enter XR, initializes the input source that will initialize the controller. It also enables the pointer selection and teleportation features in the sense of if you need to move through the application. So, for this, we just create our constant XR. Experience is synchronized. For this, we're just going to create our XR. There are four meshes. That should be it. Finally, we're just going to return our scene. And I believe this should be fine for now. Let me give a look to my working one. All right. Yeah. We're looking fine so far. All right. So, with the synchronous function, we're basically having our camera, lights, and environment, and the experience. But it doesn't have physics or any way to be rendered yet. That's the next step we're going to be moving into now. So, now, the next thing that we want to add is physics into the world. And there's plugins for physics engines available for use in Babylon.js. We have Cannon, Oimo, Energy, and Ammo. In this case, we're going to be using Cannon. But the other ones are you can find more about them in the Babylon.js site, which I can actually link to the chat right now. Basically, the Cannon.js engine is written in javascript. If you're unfamiliar with what a physics engine is, they provide an approximate simulation of physical systems, like mass, gravity, friction, and restitution to our scene. So, in our code, we're going to be adding our variable Cannon after the light intensity. So, under light intensity, we're going to create our variable for our Cannon plugin. And here we're just going to do the value of true to our delta for the world step. And enabling the physics in the scene to the physics component of our scene. Gravity vector, we're just going to do a negative 3 here with 0, negative 3, and 0 for values. And that's the physics engine that we're using. So, now it should have a sense of gravity and physics in the scene. Next, the next thing we need to do is basically rendering the scene. And for this, we need to create the engine, create the scene, and render the scene by using the engine. And then we basically just resize the engine to the size of the scene. So, under this function that we just created, we're going to be adding the following code. This is what's going to be rendering the scene throughout the whole project. So, we're going to do a try. Creating our engine. Show exceptions. See if anything happens. Log. I don't think we should run into that issue. And here we should basically just... Just in case something comes up from this. Now, if there is no engine, we want to throw... Engine should not be null. Just in case. Now we want to create the scene. Basically use the create scene function here. Home scene. The scene to render. Basically, here we should have the whole create a scene call. And then the next thing is just render our scene by using our engine. So... In this case, we're just going to do Function. Scene to render. It's true. Scene to render. As long as we declare the scene to render, we should be able to render it. And the next thing is just to resize our engine. Just in case the engine looks too big and we don't want it to... We don't want it to look bad. We want to make sure that it fits where our workspace basically. So we're just going to add an event listener. Window. Resize. Type. And the function will just be resize the engine to our window. All right. We should be able to... Still a double take here. Just to make sure. I'm getting some errors here. Or just changes. All right. So, let's wait to try it out. It's just trying to run this. We got any errors? We should know them here. I see we're showing some missing. I'm not going to go through those. That's fine. This we're going to be working with further down the line. But I want to make sure that that's not the issue we're having here. So, we're going to go back to the repository we created from the template. So, any changes that we create out of here, I'm going to undo. I'm going to restart this to the original step. Apologies for this. It's just that we are running into something that we're not running into. I'm just going to copy this. Just in case. Copy the original. The part that we had. And we're going to have to create a repository from the template again. So, I believe the code should be the same. But let me do a double tick before we try. Things happen when coding. So, I believe our code should be the same. But I'm just going to do a double tick here. So, I believe this version should be a little bit more polished. I'll give you the link in a second. I just want to make sure that I'm running through it. Oh, yeah. You're right. I'm running it on the opposite end. Thank you. Yes, this is a little bit more of a completed version, technically. All right. So, I'm going to give you the link to get the new repository. Apologies for that. That's why we always have a backup plan. So, from the link I gave you, you should be able to create from a different template. You're going to be creating a repository from a different template. And that's the one we're going to be working on. And we're going to have CodeTour, in this case, to help us go through it a little bit nicer. So, in here. Let's see. Yeah, it should have the code working fine. All right. So, this should this version should have the code with a little further steps. I'll just update you on the ones that we haven't gone through yet. But basically, the idea is the same. It's still the same process. Just skipping the errors that we had before. I don't think we necessarily need to use CodeTour here. That's fine. So, as I said, basically, we have our first we have to get the inputs that we're going to be using. We need our scene, we need our light, we need our vector 3, we need our engine, our camera, our physics engine, our mesh builder, which is going to help us build the elements inside the scene, the materials that we're going to be adding into that. Photodome is going to be allowing us to have a background image. And then our physics imposter for the physics procedures. So, again, we're importing all of these from Babylon. We are importing our cannon engine. Our procedural texture of wood is something we're going to be adding to create the floor. That's probably something you noticed on our thing here. We have a texture already added into the floor. Beyond this, we're going to be moving into our canvas. Again, we use declare our canvas variable as an html canvas element. We load our three dimensional engine. Our scene to render. We create our default engine. And from there, we basically move on to create our scene. Again, our scene we're creating a synchronous function. And this is basically adding our camera, lights, and environment. We have a scene we create our scene using our previously declared engine. We're going to be rendering that after. We have our camera variable basically with our rotational variables where we're going to be our rotational speed and where we're going to be focusing it on and which scene is going to be rendered at. Basically how we want it to rotate or real delta percentage so it doesn't rotate like crazy. And where we attach the control of the camera, which in this case is the canvas. Again, our light is a hemispheric light which means it's going to be covering the whole scene instead of being directional to one specific place. And we're placing it at the coordinate 0, 1, 0. Again, our light intensity is going to be 0.7. So, 70% of intensity. So, it's not too bright. It's not too dark. We're going to be adding our physics engine in the form of a kind of plugin. We're just calling it from the kind of plugin that we imported beforehand. We're enabling our physics through the Canon plugin and we're setting our gravity force. We create our environment thanks to the default environment function scene. This allows us to create it without having to build it out completely. And then from there, this is where the next steps we're going to be jumping into. So, I'll jump into those in a second as well as a photo dump. We created our XR experience here. And then we basically call the default engine to load our scene. We created the scene and then we render it through the engine. And finally, we resize our engine. So, basically the same code with a couple extra steps added. Now, our next steps is basically generating our wood floor. That's where we stand up here. So, basically we're going to be using what's called a mesh builder. And this is a function within Babylon that allows us to create elements or objects inside our scene. And then we're going to be using our procedural or wood procedural texture that we imported from Babylon to create a wood like texture into it. Finally, we add a physics imposter into the gem floor which is going to define the physics of this mesh with parameters that are going to be imitated in the ground. So, basically that code is what we're adding here. So, we basically created our variable. It's going to call gem floor in this case since we're talking about a gem in this sense of basketball. From there, we call our mesh builder. We create the ground so that it knows it's a ground type. We call it ground and we add the different dimensions that we want it for. So, in this case, we're adding a width of 60 and a height of 60. So, it's a decent size square. And we're placing it on our scene. The next thing that we did is position it. Basically, this coordinates that we have here are going to be affecting how our ground is positioned in the scene. So, if we modify them, the ground is going to move from one point to the other. You know the drill. The next thing is the clay or wood materials. Materials are components of a scene that allows that can be attached to an object to give it either color, give it a texture. It's basically what gives the object a more realistic appearance. In this case, we're creating what's called a standard material. And that standard material, we're going to be adding we're going to be basing it off of our wood procedural texture that we imported before. So, basically, from our texture, we're scaling it a little bit so it's a little bigger. And we're diffusing that into our wood material. And then we're adding that material into our gem floor down here. From here, this is basically adding this is basically pasting the material on top of the on top of the floor or rather assigning this value to the floor so that it looks a little more realistic in this sense. Materials you can create from images as well. You can even create import assets that you make things look nicer and import them into it and assign it to any object or any mesh that we create. Finally, the last thing is that we're adding our physics imposter into the gem floor so this can simulate a ground. This is not too important right now. The main thing we want to make sure here is that it acts as a ground. And that's why we're adding this component. The one thing we want to make sure is to that once this is being created, we replace it on the floor mesh in our default XR experience. So, beforehand we had it as environment ground here. This is what we had before. It was actually one of the errors we were getting. Once we once we've defined this gem floor variable, the floor is seen, we can replace this by gem floor. And that way we can ensure that once we run this in an extended reality experience matter, we can we're going to be using we're going to be actually positioned in this ground instead of being positioned somewhere else. The next thing is the photo dome background is what we're creating here. So, I'm going to go over this. Basically, you can create a world around you in different ways. In this in this sense, we're going to be using what's called a photo dome, which takes a photo, preferably like a 360 degree photo. And it's going to be using as a texture to create a background material in an inverted sphere shape. It's kind of like placing us inside the sphere, right? And with this, we can basically wrap a sphere with an image and it's going to be looking like a basketball. You can wrap it the inverted shape of an image and make it a background. That's which is what we're going to be doing right now. And basically, the code that we see here, it just instantiates our photo dome class, passes an image URL, and sets a size and resolution. So, this code belongs like after the code that we wrote before the to create the gem floor. So, in this case, we're using this image, which should be here. And if it loads, this is the image that we should be seeing on the background once we run our project. I know that right now it's not showing, but I'll address that in a second. And basically, we call it my dome in this case and we add the resolution and the size into the scene. Now, let me see. Because it's currently not loading. If I check. No, it's not. Everything's fine except the photo dome. So, I'm going to add the original link, the original URL here and see if that's going to help us load it. Refresh here. Should be loading. Running out of options here. Well, technically, it should be running. That's how it was running beforehand. This code was done. So, I'm trying to figure out why it's not loading right now since I'm not getting any errors now. But basically, I'll just showcase it here. This is kind of how it should be looking. Should be basically an inverted sphere inside of our project. I don't know exactly why it's not running. Maybe something we'll address further on. But currently, the code is looking fine. So, apologies again for this. This is what happens when we have too many demos. Sometimes some of them don't want to fully go through. But yeah. Basically, that's the idea. Should be creating the dome inside of the sphere and kind of placing us inside. Now, the next thing I'm going to move forward with, given that we've already created a scene and set up the default XR experience and physics, we're going to be building out the character icons that we want to display. So, in this, we're going to be using the Verlin JS GUI library. And for this, we're going to be using our GUI 3d manager and our GUI cylinder panel to manage a group of holographic button icons. So, this is how we're going to add the XR environment experience into it. So, for this, we're going to be adding some code up here. So, we're going to be adding... I believe this should be fine. We're going to be importing... Import. Import. Import. Import. Import. Import. Import. So, all these packages should be imported after. So, the next thing we're going to do is create our environment class and private variables into the constructor. So, we're going to be needing to pass a scene and import all the JSON data to an array. So, from here, basically, we should... Let me see. Oops. Sorry. So, I believe we should be having all this... I'm just going to see where we can export it into. So, basically, we're going to be exporting our class environment with a private scene or private engine, private players, and our constructor of the scene engine and so on. However, I don't know if I have this file here. Oh, no. I do have it. Okay. We're good. That's good for a second. All right. So, basically, what we're doing here is we're exporting our environment class and the private variables to map in the constructor. And this is just passing... Basically, we just need to pass the engine and scene into the class. And from here, we just import the JSON data into the array, which is what we're adding down here. So, we pass our scene, we pass our engine, and we pass our players. Now, we should have an environment with a scene, an engine to render the scene, and data from the JSON file. So, now we can create the player icons and make them actually clickable. Let me see if this is gonna give me any errors here. All right. No. We're good. All right. So, now, we're gonna be creating our character buttons. And for this, we're gonna be, again, we're gonna be bringing our cylinder panel from our Babylon JS builder. And from there, we're gonna start working. So, I'm just gonna start writing bounding here. So, this should be in their environment. So, create character buttons function inside the environment class that we're exporting. Manager here for the icon grid. So, it's gonna be a variable main button. This is gonna be our Kui two dimensional manager. We're gonna create a cylindrical panel so that the images can wrap around the user. So, basically, imagine that you're trying to select different players and you have them all in front of you. This is what we're trying to achieve from here. So, we're gonna create our main button panel. Cylinder panel. And we're gonna add a margin. And we're gonna create an anchor so that the main panel doesn't move. So, basically, we're gonna do a link to transform this node to the anchor. This is basically telling Babylon that we don't want the we want to stick to this anchor once the main button is selected so it doesn't move anywhere. We want to listen to native players. How many players do we have? We have at least 16 players. So, it should be 8 columns of 2 rows each. So, I'm gonna add 2. I mean, 8 columns. And for rows, we're gonna be adding 2. And basically, just adding block layout to these. This is gonna make sure that they have an actual layout. Otherwise, they're not gonna. All right. So, this should have a position for each of the characters within the main panel. And we'll hopefully be seeing that soon. Oh, did I make a mistake here? Oh, vector 3. Oops. Sorry. All right. And the next thing is to create our characters popup images. So, now for this, we will be adding code for the popup image that contains like our the PR value of player. So, when a player icon is selected, their stat card and their name image and the PR, which is the player efficiency rating that we have in our data, should be showing. So, if we see here, we have our basically character name, our character image, and our player efficiency rating for each one of these. And we want to make sure that these show up when you click on them or when you have the button in front of you. So, for this, we're gonna be adding I believe we should be adding this at the end of this. So, we're gonna be which is gonna be directly again managing this specific buttons that we're adding, this specific popup images that we're adding into this. So, again. And we're gonna add our mesh panel to the mesh manager and anchor it to it. So, mesh manager. Anchor. So, let's put the location. Since this is what it's gonna be when we click on them, we want it to be a little closer to the player. So, that's why we have different coordinates. And finally, we want to set the player container and add it to the mesh panel. So, we're gonna be getting the information for this. So, play stats container. And we're gonna make this accessible. It's not seeing it all the time. So, only when we click on it. So, this is just so it's not showing initially. Because the idea is that these are gonna become interactable. And that's the next thing we're gonna do now. So, now that we have a place for each of our character icons and the popup images show up large should be showing up large in the center of the screen. In fact, I believe that if I save this, I should not have any errors. And if I do, then I just have to keep moving. I don't think this should be changing much. I just want to make sure. I really haven't added anything yet. All right. So, now I want to make sure that these icons are interactable and look through the players and create a button for each player based on the JSON data. So, underneath here, we're just gonna be adding our new meshes. So, this is gonna be the mesh for each one of the buttons. So, we're gonna create a mesh. Value of null for now. This is just gonna create an array of meshes that we're gonna be accessing later. We're gonna store them. So, all we want to do now is choose that when a popup image is selected, we want to hide the player container. So, we want to make sure that it's not visible when we select the image. And once the button is there, we can just post a message. So, this should ensure that we have it. This will ensure that once we select one of the images, the player container should close. I mean, we should be hiding the player container instead of all the players and have the close button there. Now, the next thing is for us to loop through the players in the JSON file so we can create a button for each one of them, right? So, for this, we're gonna do a for loop. And so, this is just gonna be navigating through each one of the players. And we want to make sure that we're creating a button for each one of them. So, a new holographic button. Add a button to it. And now we're gonna add the button. URL. And then the final thing is for us to once the button is selected, we want it to trigger the popup image to appear. And now with the player efficiency rating. So, button on observable. Asynchronous function. Place that container. Image URL. Next. In this case, now it's gonna be visible. So, we're gonna do a scaling so that it pops up instead of just staying the same size as the others. All right. And with this code in place, we should be having our players show up in the environment. So, when we select them, their stats should be popping up. And then the next thing we have to do is just initialize our custom environment in DXR experience. So, it's like the last thing we can do before we can actually try running this. And that's basically just replacing our default environment in our file to the new one that we're gonna be creating. So, let me see. So, for us to initialize our custom environment, we should be adding an initial function. Call help for functions. So, we're still inside our environment. So, here we're gonna be adding an initial function. This is gonna be creating our character buttons. It's just basically a helper function for us to initialize everything. Okay. And well, typically this is added after the constructor. So, I'm just gonna add it right after our constructor here. And now let me see one thing. Oh, I think I might have one second. I think I might have skipped one step. I just noticed that I imported all this into the index file and I don't think I needed to put it there. Okay. I'm sorry. I completely blanked out on this. I admit I'm a little bit nervous in this sense. But basically, our environment class has to be basically brought up as a class of its own, not inside of the index file. So, basically, we're just gonna create a new file. We're gonna call it. And here we're gonna paste everything from there. That's my bad there. And I should have some imports in here, I believe. Let me do a double check, though. No, I mean, we did the export, so it should be fine. I want to disregard this for now. Not 100% sure on this. I did not see this happening there. So, I'll just delete that class for now. I just have it here. I believe doing the export should be fine. I was running into errors before. Let me see. Now, in our file here, we should be modifying this from this environment, which is the situation here. Let me see. We need to create a new environment instance. Beforehand, we used the default environment. Let's find where it was at. Okay. Here we are. So, we call it EMV. So, in this case, we're gonna be replacing our environment scene that we created before with the new environment that we that we developed. And in this case, we're gonna be passing our scene instance and scene and engine instance to it. So, here we should be doing a new file. Scene and engine. Given that we have it here, I believe that might work. Otherwise, we'll see. Let's see. Okay. Now, we might need to add this as an extra one. I'm so sorry about that. It's a slip on my end. We definitely need to import this class from a different file. So, I'll just do this. So, I should have the environment. So, I need to... I'm sorry. This is me being dumb. I don't know if we need to have this here yet or not. So, we have an environment from Babel. I'm just importing here. Okay. We're fine. I know where I messed up. Sorry about that. This is definitely environment.ts. Not yet. What I... Yes. Yes. Thank you, Rafael. I actually just noticed that I also missed the inputs here. That's why you need to have a backup to check up on things. Completely right. I should be fine now. My bad. I completely forgot about creating the file. And then, when I created it, I forgot about the inputs. That made me second guess everything I was doing. So, with this in mind, then here I should need the ts. There should be fine. There we go. Phew. I'm completely sorry about that. So, basically, when I was starting to write the environment class, the Explorer environment class, I should have created a new file. And for it to be a class. And the thing is that since I forgot about adding my emperors, I completely thought and second guessed what I was doing there. But, yeah. Basically, what we would do is create an environment.ts file. We're gonna add the inputs. In this case, they're gonna be your scene, engine, assets manager, vector 3, transform node, scene loader, and mesh. We're gonna import our player. We're gonna import our GUI. These are the inputs I added here instead of adding into my environment of class file. So, from there, basically, we can write down the code for the environment class. And from there, we should be fine with importing it in our index.ts file. So, this is technically still running. So, if we open it now, now it's working fine. So, now we can see the different we can see the dome actually working out. And we can see different buttons that we created. So, this button, if you click on it, I have a little error there. It should be showing a number. I'll look into it in a second. But basically, we created this whole scene here. You can see that we can rotate around them. We can play around with different buttons. And once we click them, you can see that they're magnified. So, let me double check on the code. It's in environment, I believe. It's our player pair. Oh, oops. Should have been curly braces. And if we double check that now, oh, I need to reset this. Oh, we lost the outset image. I'll wait for this to finish loading. It's taking a little longer than necessary. Oh, you're so right. I did not do backticks. Thank you so much. There we go. Yeah, now I need just to do this. Thank you very much, Raphael. You've been super helpful. I appreciate it. Especially when one gets nervous doing this presentation. Okay. It's not loading yet. Even though I'm pretty sure it's written properly. Okay. Yeah, that's fine. That's fine. Well, yeah. Basically, that's the general idea of Battle. It provides us with a lot of different opportunities for us to work around this. I definitely recommend checking out documentation from their website. They have a very, very in depth and useful documentation. This is still not showing for some reason. But it's fine. I believe the code was looking decent now. Yeah. Maybe their IQ LME, the website and documentation as well. There's a lot of great opportunities for building here. They have a whole section on getting started with Babylon that I believe is very insightful and very simple to follow. And that's another way of testing the capabilities of this engine. I share in the chat the documentation for Babylon JS. This is something that, again, you can test on the playground. The playground allows us to build things in realtime. I can show you how the playground looks. But basically, this allows us to run scenes live on the browser. And you can play around and create your own scene here. Add as many things as you want and download into it. So, I believe this is a great tool to practice and learn. And yeah, I mean, there's a lot of things you can build here. It's honestly a very strong engine and a very good introduction to WebXR. Again, I would like to apologize for some of the inconveniences with this. We had two methods of running the workshop. I was trying to run the more in-depth one. But generally, the easiest one and the simplest one is the best one to go by. Besides that, that's pretty much the general idea, the general introduction to both WebXR and Babylon. I'll add that with this code, if you wanted to run this experience in a headset, you could. I think the only difference is that you would have to have a WebXR supporting browser installing your headset to run it. But this can also be run in either Android or iOS, depending on the platform that you have. And it can be run on different browsers as well on there. I believe iOS can only be run on WebXR viewer, but I believe Android has more options for that. So yeah, that's the general idea of this. Thank you very much for providing me some of your time.
86 min
19 Apr, 2022

Watch more workshops on topic

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career