PlayCanvas End-to-End : the quick version

Rate this content
Bookmark

In this workshop, we’ll build a complete game using the PlayCanvas engine while learning the best practices for project management. From development to publishing, we’ll cover the most crucial features such as asset management, scripting, audio, debugging, and much more.

121 min
18 Apr, 2022

Comments

Sign in or register to post your comment.

Video Summary and Transcription

This Workshop covers the basics of Play Canvas and guides you through building a game in three phases: scene setup, interactivity, and polishing. Play Canvas is a web-first game engine that runs on your mobile device or browser, making it fully cross-platform. It provides its own hosting solution for easy sharing of your game. The Workshop covers topics like importing assets, scripting, physics, animation, debugging, user interface, audio, and publishing.

Available in Español

1. Introduction to Play Canvas Workshop

Short description:

This workshop will cover the basics of Play Canvas and guide you through building a game in three phases: scene setup, interactivity, and polishing. You'll learn about importing assets, scripting, physics, animation, debugging, user interface, audio, and publishing. Play Canvas provides its own hosting solution for easy sharing of your game.

Hi, everyone. My name is João and this is the workshop for Play Canvas End to End, the quick version. So Play Canvas End to End, the quick version. Quick, not so quick, because it will be around 2 hours of workshop. But yeah, we'll still be able to build a full game in this 2 hours.

So the way that we will structure this workshop is, so just to do some brief introductions, but then I'll talk about Play Canvas. So I'll just talk about, you know, the basic features that we have, you know, like the everything you can do in Play Canvas. And we'll go into the actual core of the workshop where we'll build a game together.

So I split that into 3 different phases. Phase number 1 is like just a general scene set up, so we'll start just importing some assets, placing some stuff around, some obstacles, some ground. We'll talk about that in a second. And we'll talk about launching and like testing your game out. Phase 2 will be about interactivity. So we'll go over scripting, question scripts, we'll go about the event system that we have in Play Canvas, also about how to do physics with rigid bodies. We'll talk about the animation system as well. And then some debugging capabilities using Chrome. And then phase 3 will be about polishing and publishing. So we'll create just some final touches on user interface, how to do audio, and then we'll be able to publish that to the world. We'll be able to do that using Play Canvas' own hosting solution, so you don't need to have anything on your own, you just press a button and you'll have a firmware link to your build of the game, and then you can share it with anyone that you want. And then we'll do some wrap-ups towards the end.

2. Play Canvas Project Phases

Short description:

We'll be using a Play Canvas source project that already contains all the assets and boilerplate code. You can fork the project at any phase if you get lost and start from there. The final project with full documentation will also be available for reference. You can choose to listen and learn or build along with me.

Now, the way that we'll be doing the different phases there in the actual game is that we'll – I prepared a Play Canvas, like a source project that already contains all the assets and the boilerplate stuff that we'll need, and what you guys will be able to do is actually is you take that and make a fork out of it, so you'll be able to copy that as your own project and then make whatever you want with it. I'll be doing the same thing, so I'll be starting from the same like, starter project, and then together we'll build up to the final game. Now each of the phases, we also have a project for those, so let's say that you're in the middle of phase one and you kinda get lost. It's okay, just wait for phase two, and then you can clone, you can fork a project starting at phase two, and then same thing for phase three. If you get lost in the middle of the scripting stuff on phase two, just wait and I'll send the link for phase three, and then you can fork phase three and restart from there, so you have these three kind of like, checkpoints that we can go along the way, and also the final project, like the end thing, with full documentation, with all the features, will also be available for you guys to take a look at, so see the entire thing done as well. So you can also just sit back, take a coffee, tea, water, whatever you fancy, and just listen out how to build the full thing, or you can build out, like together with me as you go through it.

3. Introduction to João and Play Canvas

Short description:

Hi, I'm João, a software engineer at Play Canvas. Games have been my passion, and I have launched indie games like Step and Menard. Find me on Twitter and GitHub for more.

So first, let's briefly talk about who I am. So, hi, my name is João, I currently work at the Play Canvas team as a software engineer, you can also find me on Play Canvas official forums as JPaulo, and again, as I said, currently I I work as a software engineer at Play Canvas before, I was working at Amazon Alexa and before that I was working at SAP. So I do have kind of like a back end, you know, like a not game-related until I moved to Play Canvas, but games have been my passion since like the beginning. I think there's a story that many people share I guess in the gaming space. So, games is the thing that made me really like want to go as a career as a software I do have a few indie games launched. So, I have step and Menard, which did, you know, have a little bit more of success. So Menard did reach, I think was top 10 puzzle games in a few countries on iOS when it was released. So that was pretty exciting. And Step was a game that was picked as a for the Google indie games showcase a few years ago. So there was a whole event about it as well, which was pretty cool. You can find me on Twitter as the John Paul and also on GitHub. I'll talk a bit more about why GitHub is important for us at PlayCanvas. But yeah, feel free to follow, I follow back. You know, like all that nice policy for follow, follow back. So yeah, cool.

4. Introduction to PlayCanvas

Short description:

PlayCanvas is a web-first game engine that runs on your mobile device or browser, making it fully cross-platform. The PlayCanvas engine contains all the core functionality for a PlayCanvas game or application, including vectors, math, loading meshes and textures, and GPU shaders. It is open source and available on GitHub. The PlayCanvas editor is collaborative by design, with a powerful backend that handles asset processing and compression. It supports code editing with built-in intellisense and has zero build-time. It also includes WebXR support, a Git-like version control system, and advanced graphic features. The PlayCanvas editor has a small file size and supports user interface, audio, animation, physics, and more.

So let's talk about a bit of a PlayCanvas. So PlayCanvas is a web first game engine. So as you can see from the editor there, we have on the right is very similar to a few other game engines that we have in the market. But again, the cool thing about that is that it's running 100% on your mobile device, on your browser, right? Which does mean that you can like, you can use it on a mobile device as well. But you can it's fully cross platform out of the box. So you can use it on. You can use it on on Windows, Mac, Linux, anything that you can run a browser on. You can run PlayCanvas. Maybe it even works on Raspberry Pi. I don't know if it has WebGL. Anyway.

The PlayCanvas is really spilt into two main things. So first is what we call the PlayCanvas engine. So the PlayCanvas engine is what contains all the core functionality for a PlayCanvas game to function, or application to function. So it has stuff like vectors and math and quaternions, mathematics, and like loading meshes and textures and loading that GPU shaders. So all that stuff is on the PlayCanvas engine, which is fully open source and is on GitHub. That's why GitHub is important to us. So you can you can help over there right now GitHub.com slash PlayCanvas slash engine. And you can you can make contributions yourself, you can check out what we've been doing and you can also use it like to to to learn a little bit more about how to make like game engine architecture. You know, how do we do that. The final build of the PlayCanvas engine is only 335 kilobytes zipped. So that means that when you make a PlayCanvas game and then you ship, for people to download or and to play, the PlayCanvas footprint is only 335 kilobytes. Again, that's zipped. Once you unzip it, it's a little bit more, and that's a little bit over a megabyte, still pretty small. So our footprint is very small. It is available as a standalone so you can the PlayCanvas engine without the PlayCanvas editor, which we'll talk about in a second. And so the PlayCanvas engine is on npm so you can use it from there. You can also just download the minified version and use for that.js, a single file, just import it. And go ahead. Or you can build from source. You can download the open source right there, npm install, npm run build, there you go. You have it there, you can use it from there.

Now the online editor, of course, uses the PlayCanvas engine, and this is what powers the playcanvas.com. And we really do collaborative by design. So everything you do on PlayCanvas is very easy to collaborate with other people. We'll talk about it in a second once we actually jump into the workshop and we actually do stuff, you'll see how easy it is to have multiple people working on the same scene at the same time. But it is collaborative by design. We have a powerful backend that powers everything, so everything that you do in terms of you open the editor, and you're like, oh, I want to use this mesh, I want to use this texture, all you have to do is drag it to the editor, it uploads to our systems, and then we do all the heavy lifting, like converting to the proper things, doing compression, blah, blah, blah. So you don't have to worry about anything. Yeah, so as I said, we do asset processing, texture compression, and all the modern conversion except most of the all of the major file formats. GLBs is our favorite one. FBX also works pretty well. You have a free tier as well, so we do have some paid plans if you want more deep team management functionality, but you do have a very powerful feature as well, with a lot of storage, and with self hosting, as well. Yeah, so unlimited, free hosting for published apps and games as well, which, again, I'll show you how to do it later. So just talk a bit, some of the features that Lick Canvas has. So all the code editing for your own scripts is done online as well with built-in intellisense. So we use actually the same, sorry, we use the same code editor as VS Code, but it's for the web, but it's powered by the same engine, it's called Monaco. We have the powerful back-end again that does like all that heavy lifting for the assets for us, which does mean then, as you're building stuff, you have zero build-time. So you need to wait for your importing stuff, you know, you're loading the project, it's all like it's already there. It's like basically loads up. That's a bit of the powerful backend, but also a bit about JavaScript itself that is not really a compiled language, you know. So when you're building stuff with Play Canvas, we code in JavaScript, so you don't need to, like, compile everything as you do stuff. It does mean a zero build-time then. It does come with WebXR support out of the box, we have some examples for that as well. We do have also a fully featured Git-like version control system, which again, as I talked there in the beginning, we'll be able to, like, fork projects. So this is like just a piece of that. So we can, like, fork projects, but you can also create checkpoints, you can create branches, merge back, very much like a Git-like system, which again, I'll talk about later. And the editor itself. Multi-platform. And when you load it up, is super small alone. It's only, like, 2.1 megabytes, if you check on, like, Network tab, how much have you actually downloaded it? It's only 2.1 megabytes. Again, it unzips, you know, it compresses later. But the main thing is only 2.1 megabytes. And it supports like all the things that we expect from a game engine these days. We have user interface, we have audio support, positional audio support, animation system physics. You can create templates, which prefabs, as it is called in other game engines. We also have advanced graphic features. So we have a mandatory time and a real time light mapper, physical based rendering, shadows, clustered shadows, all the stuff out of the box using Play Canvas. And we have a dozen of support channels. So we have documentations with tutorials, full API references. We have our own forum as well, forums.playcanvas.com, where you can, like, post questions. So people are very, very helpful there. Shout out to the people on the forums, they're amazing. And we also have our own Discord channel as well, where sometimes we're there just to chat and help out whenever people want. I could stay here for two hours just talking about stuff Play Canvas can do, but this is getting kind of boring. So moving on.

The Play Canvas editor itself, very similar, again, to many other game engines that currently are out there. So we have the hierarchy list on the left. We have a toolbar also there on the left where you can just select what tool you want to use. You have the project assets there in the front bottom, where you have all the assets that were inserted, that were imported into that project. You have the inspector there on the right where you can inspect your selected entity. So, for instance, in this case, I'm selecting the light entity. So you have the basic information such as the name. Is it enabled? You can add some text. Then you have the transform of position, rotation, and scale. And then you also have the components, which I'll talk about later about them. But basically you define the behavior. So in this case, I added a light component and then you can select what type of light is it. Color intensity. Does it do shadows? Is it not do shadows? Like how often to update the shadow map.

5. Useful Links and Game Introduction

Short description:

In this part, we'll explore some useful links for PlayCanvas, including the PlayCanvas GitHub repository, examples browser, API reference, and tutorials. We'll also introduce the game we'll be building, which involves a character navigating obstacles, eating food, and managing time. The game includes physics, dynamic food items, animations, and a simple UI. To get started, make sure you have a PlayCanvas account and fork the food run starter kit. Then, open the editor and navigate to the game scene.

All these things you can select there on the inspector. Some useful links. Just, you know, general PlayCam useful links. So I have this awesome PlayCanvas GitHub as well, which is a curated list of like some cool stuff that you can do with PlayCanvas. Some of them have sources as well. So you can check out like how those things were made. We have an examples browser where you can check out again like how to use the engine and all sorts of crazy stuff. And you have the API reference and tutorials. You have the froms and have a Twitter as well. So Twitter is pretty cool as well. We do like to retweet and help out the community as well. So, you know, just give us a shout out. If you have a cool project, I'll be sure to retweet and spread the word about your project. Cool, right. OK, with all that boring stuff out of the way, let's actually go ahead and build something.

So the the game that we'll be building is this one. I'll open up here just so you can see what it what it is. So this is what I was talking before about your own about having a build hosted by PlayCanvas. So this is a PlayCanvas.as website. And from here you can you can host any village. This is the game that we'll be building. It's a pretty simple one. So you have your character moving around, you have some obstacles that you cannot really cross, and then you need to eat some food. And then as you're eating foods, the time increases and have a certain time to, well, eat all the foods. And one of the game, very silly game, is just to eat as much as you want. And if the time runs out, let's let's leave the time to run out a bit. The time runs out, time's up, nice. There's some audio effects there as well. Just says time's up. And then you press the button to go again, resets the score and then you start over again. Pretty simple stuff. But, you know, we'll be touching a lot of different things here. Let me go back to the slides. Cool. So, so again, this is just a screen of what we'll be building. So if you break down what this game actually is about. So we have a ground entity there which has some physics. We have some obstacles which need to somehow block the player from going. So we need, again, some physics collisions on that. We also have some food items that keep popping up. And as you can see there, the food is not always the same. So we have cakes and apples and bananas and stuff like that. So, and it's dynamically placed. And also have the player which is, of course, dynamic as well and has some animation on it. We also have a very simple UI there on the top left, which contains, just has the time remaining and a count of the score. Cool. Now let's get going then. So we'll start at phase one. So hopefully by now, most people have the PlayCanvas account. And then if you don't, just go head to playcanvas.com and create your new account. Should be pretty straightforward. Very easy, very fast. And then we'll start with the food run starter kit. So I'll send this link on Discord, and I'll also send this link here on the chat. Which is this one right here. So just open that up. It's public, so everyone should be able to see that. And from here, let me close chat, right. So from here, we can go ahead and fork it. So to fork a project, simply go here and click on the fork button. So the owner should be, like, this should be your name, should be your account there. And you can call it whatever you want. So I'll call it food run my own food run. Just click on fork, just wait a while for the backup systems to duplicate the project. So duplicate everything, scenes, assets, scripts, everything. And it will create your own copy of the project. So here we have. So now I have my own food run that you can do whatever you want with it. So like, every one of you have your own. If you're having any issues at all with it so far, just just send a message on chat or on Discord. I'm seeing those. There's nothing. I'll assume everyone's kind of following along. I won't be too fast on it. I'll give you guys some time. But once you have the fork done, you have your account, and you have your fork done, just click here on the editor. So it's just checking if there's anything. So I'll close my other tabs here. It doesn't get in the way. Just check if there's anything, nothing on Discord. Nothing on chat so far. Cool. Right. So once you-. So this is the first thing that you see when you open the Uplay Canvas editor. So you're greeted here with the list of scenes. So by default, when you create a new project you'll have a blank scene. In this case, we already have a game scene here. So we're going to go ahead and open up. And now we're good to go.

6. Creating the Ground Plane and Applying a Material

Short description:

We'll start by creating the ground plane. We'll make it 25 by 25 and apply a texture to it. We have predefined primitives to use, and we'll choose the plane. We'll also create a material for the plane and apply a grid pattern texture to it. The material is not yet being used on the mesh.

So as I said before, so here on the left we have the hierarchy, we have a toolbar here, here we have all the assets. On the right we have the inspector. Here we have the viewport, that is what we currently have, which again is nothing. We have actually-. No, we have a camera and we have a light source. Right? Now again, so this is like the starter project for the FoodRun game, which means that already added here on FoodRun, already added all the assets that we'll be needing for the project. So for instance, if you open Arena and you open textures, you already have some nice textures here, some prototype textures. Now all of the assets that we're using here are from the amazing Kenny, of course. I think most people here might know who he is. I think that's an amazing creator doing some fantastic stuff. And it's all CC0, of course, but all the licensing and source information are there, so just to link back to their amazing work. So we have the Arena with some textures. We already have some sound files as well that we can link later. We already have the model as well, which contains, which has the fbx file here. We have some animation clips as well. So everything is here that we'll need. And you know, as we go through the workshop, we'll go through all of those together. But moving on, we also have the script, a folder called Script Templates here. So of course, like building the entire code for that thing in two hours together while we're sharing screen might not be ideal. So already, have the boring code is mostly done, you know, like hooking up game managers and like coding the simple game logic is mostly already there. But we'll need to do some stuff throughout the workshop to fix it up. We'll do that together. But again, don't worry about those for now. I'll tell you when you need to use those. For now, just leave them there on Script Templates. Also, I do have some notes here just so I don't lose myself. So if you see me like looking down, writing down, I'm just making sure that I don't lose anything. So yeah, cool. With that, I think we can get started. Hopefully most of you have created your own fork and already have it. Let me check the chat. Okay. Can I get at least one yes I'm able to do it? Just so I can go ahead. I want to be sure that... Awesome, thanks. Awesome. Thanks, Mike. Thanks, Rick. Oh, awesome. Thank you. Ah, amazing. Great response. Thank you, guys. Cool. So let's start then. Let me just grab my mouse here so it might be a little bit easier. Cool. So let's start from the biggest thing. There's one more chat. Sorry. I'm just watching. That's totally okay, right? Yeah, totally fine. Glad you're with us. Cool. So let's start creating just the ground plane. Right. So let's start creating a new entity here. Son of root. We call that arena. So we have the arena here and let's create the ground plane. So if you go here for a new entity, we have a lot of like predefined stuff and one of them is primitives. So we have stuff like boxes and capsules, cones, et cetera. We will want a plane, which is again, just two triangles, just a simple thing for us to define a plane. And let's make it big to cover a lot of things. We'll make it actually 25 by 25, 25 by one by 25. So plane canvas Y is up. So we have a big plane here. And let's create a material for that as well, so let's apply a Texture to it. So if you go on Food Run here on arena, we already have some nice textures here, so let's create a new material there. Let's actually do some nice project management. So we'll not create it here, on arena, let's create a new folder. Let's call that one Materials. Let's create a new material here. So then on the Assets panel right here, let's create a new asset. Let's call it- Let's create a new material. Let's call it Ground Material. And this is, as I mentioned before, plane canvas supports full PBR. So physically-based rendering materials. So we have stuff like ambient, diffuse, specular, you even have clear coat, which is useful for like cars and stuff, pretty cool. We have emission, opacity, blah, blah, blah. This one is pretty simple. We just want like a nice- Let's actually refer back to our image here. Might be useful. So we just want like this nice grid pattern right here. So just like apply a diffuse here. So if you open up the diffuse drawer here, we can apply any texture here. We can also apply some tinting, some color. So let's then open the- Click on the textures folder here and let's use sector 8. I think it's a nice one here. Because I did it before, right? So when we applied here- Oh well, of course we applied to the material but the material is not being used on the mesh yet.

7. Customizing the Plane and Creating a Player

Short description:

To customize the appearance of the plane, we can add tiling and change its color. By dividing the size of the plane by two, we can achieve seamless tiling. To add color, we can adjust the tint property in the material. A greenish tint, represented by the hex code 59D1DD, gives the plane a grass-like appearance. However, other colors or textures can be used. Now, let's create a player.

Let's jump back to the plane and let's be sure to use the ground material on that plane. So we can either drag and drop here on the world so this works or here on the material slot on the inspector. So let's draw here, let's drop here because this is a pretty cool feature. Right, but this is looking very big, you know it's stretching across the entire thing. So let's add some tiling here. So a good number that will work here since this is two by two is if we take then the 25 and then divide by two. So if you take 25 and then divide by two which works by the way here, this will tile seamlessly here then and this will also line up perfectly with our grid. So each tile here is exactly one unit, one meter, whatever you want, one unit across, which is pretty cool. So now we have our thing here but it's looking very white, right? This is looking too bland. So let's give it some color. So again, if you go back to the material and then diffuse, we can click on tint and then we can add any color that you want. So we'll be able to change to any color that you want. We'll just multiply the colors together. So a good number that we have there is that nice greenish tint, which makes it look like kind of a grass. So the number for that is 59D1DD, have it written down. So this is the same color that we have there on the example, right, that we have here. So again, if you want to use the same number is 59D1DD, so that's the hex code for this nice green tint, but you can put whatever you want. You can also use another texture if you want. Not even use a texture, but cool. We have our plane here. Let's go ahead and create a player.

8. Creating Player and Obstacle Entities

Short description:

To create a player, we'll create a new entity and add a mesh to it. We'll also create a material and assign it to the mesh. The material is a PBR and can be customized with different settings. We'll create a template for the player entity, which will be useful for placing it in multiple locations. We'll follow a similar process to create an obstacle entity, using a box shape as the simplest obstacle.

So to create a player, let's create a new entity then. Not on the arena, because the arena will be putting the static stuff. Let's create a new entity, son of root. Let's call it player. So the player entity currently doesn't have anything. Let's put that mesh that we have. So here again on foot run, character, medium FBX. So this is what happens if you take any FBX file and you simply drag it into to play canvas, I didn't touch this at all. This is the raw files downloaded from Kenny website. This is what we'll create for you. So it will upload the raw FBX file and to convert that to all the files that internally play canvas needs. Now there are two more important ones here. One of them is the like the material that it uses. So this is just like important raw material which is doesn't have that texture on it. But well, it's the material of the settings that it had. And this one with the, this prism diagonal. I forgot now the name for this symbol right here. But it's okay. Square. Rotated square. And this is important because this is the template. Now we'll talk a little bit more templates in a second, but this is the asset that contains the model and the material. Everything kind of bundled together will be on this one. So this is the one that we'll be wanting to use whenever we're importing models in. We'll use this one. So then what we can use is you can take this one and we can just drag it into the scene. So we can drag it here, but I actually want to be a child of player. So I can just drag it in here. So I'll be dragging to the player entity there. Now we have the model there. Now, of course, it's still... By the way, if the camera is kind of all wrong, you can press F. You cannot really see that, but I just press F and you zero in on whatever you're selecting. So if you're selecting the arena and you press F, you go to the entire thing. If you press the... If you use another character, zoom in there, very useful feature. So now we have the R asset there, but of course it does have the material yet. So let's create a new material as well. Again, let's do some nice project management. Let's create a new folder, not to create it anywhere. Let's call it materials. Let's create a new material there. Let's call it PlayerMaterials. Of course, we could just take the material that was already imported, this one, and just edit this one. But I think for our use case, we'll be creating our own so that we can tweak some more things. So then let's assign this material to the mesh there so we just drag and drop. Doesn't look too different, but that's okay. So let's select the material. Let's go under Fuse and then let's select one of the textures. So on this particular Kine Asset pack there, it comes with four different textures and all of them already have the correct UV mapping for this particular model. So we can use whatever one we want. So I'll be using Zombie Sea but I think it looks pretty cool actually. So I have this nice zombie here already applied there. And as I said, the material is a PBR, so it's physically based rendered, which means that we can change a lot of different settings for whatever look that we want to have. So if you open the Specular Drawer here, we can do some more things as well. So we can have different specular tinting if you want that gives some nice, interesting effects. But what I want to touch on is actually the glossiness. Because if you go ahead final, the last parameter here, glossiness, and we put it like all the way over there, kind of looks like a plasticy thing, like this looks like a plastic doll, which could be something that you're going for, you know, it gives a nice specular highlight there for the light, right? So this is the light being reflected. But I think for this one, I don't really want that effect. I want something more diffused as if, you know, like as if it was a person or like a character or like some plastic that you're moving around the board. So if I bring the glossiness down all the way to zero, it kind of does this like more diffuse effect, which again, it's something that you want. You go ahead and do whatever you want. If you want like that plastic look, might even look cool, anyway. So right, we have that done. So let's create a template for this. So it's very useful as you're developing things. If you're like going to place them in multiple different places to create templates for it, which in another game engine, it's also called the prefab, which is something you can just like drag and drop and already contains all the material mappings already contains like all the hierarchy that you set up. So let's create a template for the player, which currently doesn't have much. We only have like a player entity with the model here, but we'll do some more stuff later, right? So on the character folder, let's create a new folder here. Let's call it templates. Again, we want to have a nice project management here. And the way that you create templates in Play Canvas is the following, you select the entity that you want to have to create a template from. So in this case, player, so the player entity, right-click, template, new template. This will create a new template in whatever folder you're currently on the asset, on the asset panel here on the bottom. So just create a new player template on my templates folder in the characters sub-folder. So again, so it's on foot run, character templates, have the player template right there. So if we delete this, oh no, you just drop it back in and have the full thing exactly how we had, had this setup before. Cool. Now let's, let's go back to, to the, to what we're building, right? So we have the, the, the, the player there. We have the ground. Let's create some obstacles. Now to create obstacle. Again, it will be similar to, to what we just did because we'll also be creating a template out of that. So let's create a new entity. Let's call it obstacle or whatever you want to call it. And then from that, let's create, let's create a box shape. That's the simplest obstacle that we have, right. So right here is just like some box shapes. Let's just create a box out of it. So on obstacle, let's create a new primitive box.

9. Creating Obstacles and Food

Short description:

In this part, we create a box obstacle and customize its appearance. We also create a new material for the box and give it an orange color. The box is then added as a child of the Arena entity and a template is created. We also place some obstacles around relatively randomly. Next, we create a food entity that can be picked up to increase time. The food entity is placed in the scene and a model is added to it.

Try that box. Let's move it a bit forward here so that it doesn't get in the way. It's easier to see. You can also see like the shadow map. They are being updated. Pretty cool. Let's raise it up a bit. So that's above the ground. So the value that you want is 0.5. So by default, the primitives are one by one by one. So if it's 0.5, we get it halfway there. Let's make it a bit bigger. Let's scale up two on X and two on Z. Just it's slightly bigger there but not too big as well. Not going above because we want to see what's behind the obstacles. It's just really something that they won't be able to go across.

Now let's also create a new material for this because right now, this is using like the default material, which is just pretty bland. Let's go on Arena, Materials. So the same photo that we have the ground material, let's create a new material for that. So let's call it the Box Orange or something. It'll be orange, spoiler alert. Let's drag that in. It doesn't change much because it's the same color. But now the box is using our custom material. Let's go ahead then and we won't be using a texture for it but we can just give it a color. So whatever color you want. So here I wanted to have the nice orange thing. I think it works very well with this greenish blueish background here. So the nice color for that is FBB057 to give this nice orange tint. But again, you can use whatever color you want. This is just color that I used FBB057. And you have it there. Let's create a template out of that. So in Arena... Yeah, because this will be part of the Arena, right? Yeah, this makes sense to be part of the Arena. Let's place the obstacle as child of Arena as well. So our Arena now has like the ground plane and also has an obstacle. Let's create a template out of it. So let's create a new folder. Let's call it Templates. And an obstacle, let's create our template out of that. So now you know the drill. You're pros at this already. So just right-click on the entity, Template, New Template, on the folder that you want. Like if you create on the wrong folder, just like move about... like we'll do the heavy lifting. I'll like, the referencing will be correct, then you need to worry about that. But yeah, so if you create it on the wrong place, just move it to the correct folder. So we have here on Arena, then templates we have on the obstacle. Cool. And by the way, when you do that, this one is already linked to this. So if we move this, if we change this template, like it will be applied. So we don't need to worry about that. What we'll do, let's also take this opportunity to put some obstacles around. So of course here, I made this pattern of... whatever. It's kind of nice, there's a symmetry to it. But you can do whatever you want. So in this case, I'll just like be placing those around relatively randomly. So I'll put this here. And then. So you can right-click and say duplicate, or you can do Cmd D, or I think in Windows is Ctrl D, to just duplicate. And then you can move about however you want. So let's just put some around. And I think this is a place where you can let your game design passion shine. So we can build some corridors if you want. You know, you can build some nice structures of different areas that you want. In my case, it's pretty boring just having some around. I'll put one more there. Yeah, okay. Cool, there we go. So just some scattered. Be interesting to see what you guys come up with. So again, like once this is done make sure to take a screenshot, post on a Twitter, and take a look what you guys come up with here. Cool, so now we have our obstacles. What else can we do now? Let's create the food, right? So we have the food entities there, which we can pick up to increase time. That's very important as well. So let's create one of that. So again, on root, let's create a new entity. Let's call it Food. You can call it Food or Collectible or whatever you want. So it's right now placed right there. Let's move the player back a bit because it's on the center. It's moving back a bit there. That's fine, just whatever you want. Just so it's not just out of the way. And then let's put in a model. So on your Food run asset folder here, you have the Collectibles folder. And within here, we have the models. And again, this is the raw FBX imports.

10. Creating Templates and Adjusting Lighting

Short description:

To create a template for the apple, we scale it up and create a new template out of it. We can create templates for other models as well. To improve the look of the scene, we can adjust the ambient light or use cubemaps for environment mapping. By creating a new cubemap asset and defining six images, we can give lighting and an environment to our scene.

If you just download Kenny, take the FBX file, drag it in. This is exactly what you have. It create a folder for you, which contains all the assets that you need. It have the mesh information here. All the different materials that you need as well with already all the tinted information. Again, I changed nothing out of this. This is plain import. And you'll have the diamond. I think that's a good name. You have the diamond shape right here, which again is our template. And this is what we want. This is what we want to use right here. So let's take... Shall we take apple, banana, or cake? Let's take apple. It's a more healthier option. So let's take this one. Let's drag it in as a child of food. And it will be there. It's looking kind of small. And we want to be able to see it later. So let's select the model entity here. Let's scale it up. So on the toolbar here on the left, you can select the scale. And then if you click on the... If you click either of this, you can scale up in any of the axes. But if you click on the middle there, you can scale all of them up together in a different fashion. I think this is kind of what we want. We want to make kind of big. Yeah. I think that this is a big apple. Cool. Now, since we have that, we're good to go. Let's create a template out of that. Let's go on collectibles. Let's create a new folder. Again, you know the drill. You're pros, project management, blah, blah, blah. Templates. Then on food. On the food entity, let's create a new template out of it. Cool. Again, in this phase we're doing project setup. We're creating all the different little aspects that you need for the game. In a real world scenario, you would have something like an image from a designer or something that explains the game play. It would be like breaking down all of that. That's kind of what we're doing. We're breaking down the core game play, creating templates for it. Then we'll go from there on phase two. We have now our food. Now, again, I did add some other models here. So you can go ahead and create some new templates. I won't go through all of those, but it'll be a pretty similar process. Just create a new entity, add your model. Again, the diamond shape one. Increase the size a bit so it kind of makes sense. And create a new template out of that and just place it on the templates folder here. Again, I'll just use the Apple for now. Cool. Now, if we compare this with this, it's looking a little bit different. So these shadows right here... So we have the shadows, but they're not really that strong as we have here. These are pretty like strong shadows, looking kind of gray. Also, our background is this monocolor. Yeah, that's not really something that we want. We want to kind of improve the look of that. So you have this nice like greenish thing, which kind of looks nice. So the way that we can do that in Play Canvas is... So we support two different kinds of environment light. This is what we're missing, environment lights. So if we open here on the toolbar, the last option there, settings, the little cog, you can open... So we have a lot of interesting settings here, like some editor settings, stuff like grid divisions, camera, near and far for the editor, locale stuff, you can select the engine. So a lot of cool stuff that you can do here. But what I want to touch on, is the rendering drawer. So the rendering, you can select your ambient color, you can select like tone mapping, you can select gamma, you can, we have fogs as well, so like linear exponential, you can set like a target resolution that like all your things will be kind of based around. So a lot of interesting things here, very technical. But the thing that we're worried about here is the ambient light, it's environment light, this is what we want. So if we just, the simplest one would be just changing the ambient light, right? Because if you just like bring that up, okay, that's already looking kind of better, because now the shadows are not that strong. You know, if you put it all the way down, we either have the main light or we have nothing. So if we bring that up, we have like this kind of stuff, right? But I think you can do better. So we do support cubemaps for environment mapping, so this is what we're talking about environment mapping. And you already have that right here. So if you open on food run environment, we have... This six faced... Might have seen this kind of images before. So we have six images which define a cube which we can use that to give lighting and to give like an environment to our scene. So we can very easily do that by the following. So on environment, let's create a new asset. Let's call it a cubemap, so new asset, cubemap. Let's call it environments. And then here you can see that there are the slots for six images, which again will define that cube.

11. Phase One Wrap-up and Phase Two Introduction

Short description:

We learned how to create and manage assets, use templates, and utilize the launch tab for testing. The launch tab allows us to see the game from the camera's perspective and make real-time changes. The Editor Link feature connects all tabs with the launch.playcanvas.com link, enabling collaboration and testing across devices. We also discussed the phase one wrap-up and provided a project link for phase two, where we will explore physics, scripting, and animation.

Right? So if you take a look at each of these images, their names are already like pretty self-explanatory on what they want. So this for instance is the back one. This is the bottom. This is front and et cetera, which exactly those names right here. So we have a bottom, we have a back we have front blah, blah. So if we take any of these, for instance, the first one is the back one. If we take this one and just drag it to the back it will automatically see, Oh, you have more images here. All of those have the same names. So I'll just apply all of those here. Now we have like the, our cube map already set up there. And once we do that, we do want to click this button right here. This magic button. You may need to scroll down a bit. Pre-filter cube map. So what this will do is. Basically, create different MIP maps for those textures so that we can properly use. So Play Canvas properly uses it on environment mapping. So just click the button. And then if any of these textures changes it will need to delete. And then re generate that will no changes. So this is fine. Now, if you go back to the settings here on the little cog on the left we can just use this environment cube map as the skybox. So we just pick that, drag that in the skybox. And then, ooh, okay, here we go. So now we have something there. So now we have that nice... It's using the environment to calculate the ambient light so it's not like a fixed color. And we already have this nice background here. Also, here on the settings you can change the MIP level. MIP level is basically the amount of details that will be there. So if you use MIP level 1, we'll be using the raw texture. Which, if you try to stretch it out across the entire thing, you'll need a massive texture. And as you can see this is kind of looking not so great if you're using MIP level 1. You only need like 8K textures to make this look great, which you might want. But in our case, our images are pretty small. So let's cheat a little bit and let's use a smaller MIP levels or a higher MIP level for a smaller texture size. So that's three. So then it kind of blurs out and you cannot really see the details. And it looks kind of nice. Cool. So this is the end of phase one, actually. Yeah, so with this, we have already our project kind of set up. Let's go back here to the slides. So what did we learn? We learned how to create and manage assets. We learned about creating and using templates. Oh, we didn't use the launch tab. Let's use the launch tab, actually. So as your building stuff, you will be able to see, like okay, what I'm actually building. So if you go here on your viewport, there's this small launch button here. And if you click that, it will open up a new tab, load up the game. And this is exactly what the camera is seeing. So if you go here and then we select the camera... So this is what the camera is seeing. Right there. So this is what we call the launch tab. And this is like your game running, right? So if you have scripts, once you have scripts, this will be the actual game running. While this is just like the editor, right? Now the cool thing is that if we move some stuff around... So let's say I don't really like this obstacle here. I want to move it around. I want to put it here and I want to put this one here. As you're moving stuff around, your launch tab will automatically change as well. Okay, we couldn't really see that. Let's move the apple, the food. So if the apple actually was right there and you jump back, so it automatically moves. So this is called Editor Link. So every single tab that has this in open with the launch.playcanvas.com, will be connected. And as you can see, this connection is like on the internet itself, which means that if you're building a mobile game and you will open exactly this link on your mobile device and you log in with Play Canvas there, it's super easy. You can check the differences on a mobile device as you're doing the changes on the editor. It's real time. And this is, again, what I was talking about before about collaboration as well. So if you have like some people testing, some people building, like all these people connected together on the same scene and you can all test together. Okay, like, what do you think about this? Okay, what about this? Is this color better? And then everyone kinda sees in real time as you're making changes. So this is the launch tab. Yeah, sorry, I forgot about that. Okay, now we have the phase one wrap up. So we talked about the launch tab and we talked about the editor link, right? Before we move on, so actually as we move on, so to next phase. If there are any questions or anything like that, please do drop them on chat either on zoom here on or on Discord. Otherwise, I think we are good to go. So for phase two, again, as I promised before, we have the project just for that. So I'll be dropping the link for it on, on things here. So you can use this project. You can fork from this project if you got lost in a way and you want to start exactly from this stage, exactly from the stage, just go ahead and fork this project. Let me place it here. Let me also paste on this code. So now, so that's phase two, right? So for me, yeah, I'll just like continue from this and for you guys as well, like you can continue from your current project or if you think it's not looking that great, you can like feel free to fork it as well. Cool, let's go, right? Now for phase two, we'll be introducing other cool stuff. Now we'll be doing physics, we'll be doing scripting, we'll be doing animation. Oh, lots of things go through, paper is big. Cool, so let's start with physics. First thing we'll do about physics is let's start from the same thing that we started on the phase one, which is the ground.

12. Adding Collision and Rigid Body Components

Short description:

To add collision to the plane, we need to add the collision component and import the physics module called Ammo. After adding the collision, we adjust its size to match the model. We also add a rigid body component to make the collision rigid. The same process is applied to the obstacles. By creating a collision and a rigid body component, we ensure that the obstacles cannot be passed through.

Let's just give, make sure that the plane has a collision on it. Because right now, it only has a render component on it, right? So here, if we select the plane entity, it only has the position, rotation, scale information. It does have a render, it has a render information, but there's no collision on it. So let's add that. Now, the way to do that is we simply need to add components, which will add behaviors to this entity.

The one that we want is collision. So if you just click here on component, you can see like all the components that we support. So you have stuff like audio stuff, which we'll talk to you on later. You can have cameras, elements. So this is for like UI stuff. You have model for rendering. We already have a render component, so we can't add that again. We have scripts, which we'll touch on later. What do you want is collision.

Now the first time that you add a collision, you get this scary red button, say, ML module not found. Now, what this mean is that Play Canvas on its own, we do not have a physics engine and we don't ship with one because most people don't use a physics, the physics module. If we ship all games with physics, it will make all the builds too big, so don't really ship with that. Then if you want to use physics, you need to import that manually. But manually is just clicking a button. Just click on Import Ammo. Just give it a second. You'll see here on your assets that he created this new folder called Ammo and some files there. Now Ammo is the name of a very well known, respectable physics engine with JavaScript. You can search later. You also have some documentation explaining what it is about, how to use it, et cetera. For our purposes, this just means that we imported the physics module and now we're able to use physics in our project.

Now if we select our plane again with the collision, now it doesn't have the scary red button anymore because now we already have Ammo there. Just forget about it now. We're done. We're set up. We have Ammo. Now let's just make sure that the physics collision is the same size as the model itself because when we create, we can see here. So this is the preview of the collision. But we needed to go across the entire thing. Let's make it big as well. It uses half extents. So half extents is half of the extent. So if our scale is 25, we just want to be 25 divided by 2. So that would be 12.5. And also the same thing on z. So plan point divided by 5. So you can do it or within this extent, oh sorry, 25. Let's also bring down the Y. Read it down. Y can be like something. Yeah, this should be fine. So that's really small. Yep. So now we have a collision. Now the thing that we also need for a collision is a rigid body. Because if you only add a collision, this will be treated as a trigger, which means that things will, like, go through it. But it'll just, like, it'll just let you know that it went through. But we also want to, we actually want to make it so like, this is a rigid thing that you cannot really go through. So we'll add a new component called rigid body.

Now rigid body needs a collision to work, right? So let's keep it a static. So we'll not be moving the arena about. But let's increase the friction to 0.5. So that the player doesn't just, like, slide about as it walks around. Let's put it at 0.5. Restitution is fine at 0.5, because things are not really, like, bouncing around. But let's increase the friction. If any of these things are like, oh, what is this? What is static on render? What is layers? You can just hover with your mouse, and then it'll give you a nice tool explaining what it is, and a link to the API reference to it with more information. So this is, for instance, the layer documentation for the Render Component. Very easy, just hover with whatever thing you don't really understand. Oh, what is friction? Oh, this is friction. What is restitution? Hover, click on API reference. It'll give you a job of explaining much better than I could. So let's just move forward.

So we have now the collision for the plane. Let's also add collision to the obstacles then, because you cannot really go through them, right? So the obstacle, any of the obstacles that you created, if you did a template, this will work just fine. Let's create a collision there. So same thing, create a collision. Let's make sure that it covers the extent, right? So I think this should be one. Yes, it should be one because I made it with two. Right? Cool. There you go. So now it's covering the entire size of the obstacle there, the entire model. But again, we also want to add the rigid body thing. Right. Make sure that it's actually a rigid thing. Let's just add a rigid body. Let's keep friction and restitution the default values. And again, let's keep it as static because we want to really be moving that. We'll create new types of rigid bodies later. So the player won't be a static rigid body. Moving on. So you can see when you created new stuff, since this is a template, it highlights with this blue tint and gives you here on the top this template instance override information. So this means that this instance of the template has some modifications which the raw template does not have. And then we can either keep it like this, only this one has these changes, or we can apply to all the different templates that we duplicated there. It's very, very cool that you can also press view diff here to see exactly what changed.

13. Adding Collision and Rigidity to Game Entities

Short description:

We added collision and rigid body components to the obstacles and food entities. The collision component allows us to detect collisions with the player, while the rigid body component ensures that the obstacles cannot be passed through. We also added a collision component to the player entity, using a capsule shape to enable rotation and movement. The player entity also has a rigid body component for interaction with other objects. We applied these changes to the respective templates to ensure consistency. Now, let's move on to scripting by using the player controller script template.

Oh, so now we have collision and rigid body, so there's new components there. Okay, this is exactly what we want. When you press apply all, it applied to the template which will then apply to all the instances of the template, right? So now, if you select any other of the obstacles there, all of them will now have the collision and rigid body which is exactly what we want, so very easy to apply that to all of them.

Cool, now let's add a collision also to our food there because, again, referring back to our gameplay, once you collect the apple or the cake or whatever, something happens, so we need to check when does that happen. So let's add a collision to our apple as well. So, selecting the food entity or whatever you call it, let's also add a collision. So, same thing, add component, collision. Now, for this one, we don't really want the player to bump on the apple or banana on the floor and bounce back. We want to actually pick it up. So it's not a rigid body, it will just have a collision. But with this, we'll be able to add a script which will allow us to know when a player collided with that. So with this, you can select the type of collision that you want. I think for this example, a sphere works very nice. Let's just increase the size of the sphere a little bit. Yeah. So it covers a little bit more than the actual size of the mesh but I think that's fine. But by the way, if you want the collision to be exactly right, you can use mesh here and then you can select the actual Apple mesh to be the collision, right? If you want to be exact. It's a little bit slower but depending on the mesh or depending on your use case, you might want the exact physics collision there. But again, on our use case, I think a sphere is more than fine and you can also check here the kind of preview of where it does. It's like there's a halo around it. I think that's fine. And again, let's be sure to apply that to our template. So apply all. Now we've applied to our food template. And again, if you have more than one food templates, make sure to do that on all templates, otherwise some foods will not be collectible.

Cool! And now, finally, so we have collision everything except on the players. Now let's add collision on the player as well. So now I'm selecting a player entity here on the player template better, which again, is the one that contains the character medium here, which is the model. Let's add collision there. So here, let's add a new component, same thing, again, guys are becoming pros at this. So add a collision. Now it's very common for characters like this to be capsules. And a capsule looks like this. So it's very easy to control this, to be like a character that can rotate around and bump around and multiply, really bump into things as it's rotating. It's a very nice shape to use for that. And what we'll do on the capsule, let's increase the height to three. And let's make the radius 0, I think 0.5 is fine. Now what happens here is that the capsule, the collision has its bounds around the center point, right? So right now it's using whatever this is. So if you want the player to actually fit inside that, we'll need to take our character model and move it down a bit. So since the size of our collision is three, what we'll need is to select our character medium and then set the wide minus three divided by two. Oh, sorry, minus three divided by two, sorry. Minus three divided by two minus three divided by two. And then let's just put that back into the, back into ground level there. So that should be around 1.5 then. So now our character is again on the ground, but we place the collision in the right place. I think that looks kind of okay. There's no collision on the head, but I think it's fine for our use case. This should be fine, okay.

Now again, we do want the player to bump into stuff, so the player is a rigid body. So let's add a rigid body component to it, toward the player, so the same one that has the collision. But this one won't be static, this one will be dynamic. Once you change from static to dynamic, a bunch of new options open up. And again, if you have any questions about what these numbers mean, just hover over this, and then you can see the API reference, you can see some hints there. This is similar to some other game engines as well, where in terms of like, what mass, lean damping, et cetera, et cetera. I'll give you the numbers that I'll be using, that also you're able to see on the full projects later, but if you want to use the same numbers as me, so mass is 100, linear damping is 0.9999, so four nines, so it's not exactly one, otherwise it wouldn't move, but it's almost one. This is to prevent the player from skidding across, so you're moving around, and it only moves as you're adding force width, otherwise it will stop, we want a number close to one but not really one, 0.9999 works well. We'll be using that same one for angular damping, so 0.999, and we'll also be using the same number for friction. So you can just copy that same number, so again 0.99999999 for linear damping, angular damping, and friction. Now what do these do again? Is make sure that the player feels nice on the ground that you have set up. Feel free to change it, you know, to play around with those things. Maybe your game has some cool skinny mechanics. Maybe the floor is actually ice or something. Just go crazy with these numbers. But the one important thing though is on angular factor, we want to put zero on x and z. And what do these do? This prevents our character from like topping over because if you think about it, if you think this is a capsule, on the real world, and you try to put it like this it will fall over, right? But that's not really what we want. We want it to be the character like standing like this and just walks around like this. It must be able to rotate like this. So this is why we kept the y at one so that it can rotate on the y-axis. But we don't want it to rotate on the x-axis or the z-axis. So we put that to zero on the angular factor. Linear factor needs to be one, one, one because it can move in all directions. Maybe not on y but let's keep it at one. We just don't want it to rotate on anything but y. So this is my setup. That again, feel free to use your own numbers. This is the one that feel okay here. And you can take a look into those later. Let's apply those changes to the template now. So I'll click on apply all. Let's move forward. We need to keep going. I talk too much. Cool, so what we'll start now is we'll be using now the script template. So we're moving into scripting now. Let's start with some scripts that we have here. On script templates we have already some again some templates. You know, some boilerplate code for most of the functionality. We'll be starting with the player controller. Find the player controller.js on script templates. Let's move it somewhere that makes sense.

14. Creating a New Folder and Customizing the Editor

Short description:

Let's create a new folder called player and move our script there. The online editor is powered by Visual Studio Code and has various themes to choose from. You can also adjust the font size for better visibility.

Let's create a new folder. Let's call it player, and then let's move our script there. So again, a player controller. Let's move it to that player folder or we can keep it there. But I think this is... I think this is work better. And then let's... if you double click there, it will open a new tab with the script. Now this is the online editor that, again, is powered by Visual Studio Code. Now the theme that I'm using is actually the same one as Visual Studio Code. But if you guys want to change it, I'm not sure which one are you using. But if you go here on edit preferences, you can change the editor theme as well. We have a bunch of different themes that you can use. And I'll say increase the font size so you can... Here you can see it better. Let me increase it even more so you can see it even a little bit better. 18. But again, you can use whatever theme you want.

15. Scripting and Input

Short description:

Scripts in Play Canvas are 100% JavaScript and are loaded and applied to your website while the game is loading. The player controller class is created using the PC.createScript method. The initialize method is called before the first frame, allowing for setup, while the update method is called once per frame. Input can be added using the keyboard.isPressed method, allowing for movement based on key presses. The apply force method is used to apply movement to the rigid body. Scaling may be necessary depending on the desired speed of movement.

Now, scripts in Play Canvas are 100% JavaScript and they are loaded... They are downloaded and applied to your website, to your code, while the game is loading. Which means that the way to create functions is to define what the functions are. In this case, we have the player controller. And this is what line 1 is telling us. Line 1 is telling us we have a new class called playerController variable. That is a class. And we're calling the PC.createScript method. Now, this comes when you create a new script from... From start, if you just like create a new script, like this boilerplate code will be there, which is a brief explanation. This means that you're creating a new class called playerController that is a PlayCanvas. So, PC is PlayCanvas, a new PlayCanvas script. This is what this is doing. Don't need to worry too much about it. Now, the first method that we have here is the initialize method. This is called, before the first frame, that this script is enabled. So, if you have an entity that is enabled by default in your scene and you start the game, this will be called right before it starts rendering. So you can set up internal state and et cetera. The second one that we have here is the update, which is called oncePerFrame. Now, important thing is, this is once per frame literally. So, if your game is running at 30 FPS or if the game is lagging a bit and for a few frames it runs like 10 frames per second, this will only be called 10 times. So, for that reason we have DT. DT is a number that is the delta time. This is how much time in seconds it took since last frame was rendered. We can use this number to scale movement and make sure that we don't lag behind too much. So, we have initialized and update method. So, as you can see, our particular boilerplate code here already has some stuff in. But it is missing some stuff, right? So, the first thing that we're missing is input. So, we're doing some, we're initializing some methods, some variables. You have x and z for x and z movement. And then we're already applying that force to the rigid body if something happened, right? If you have some movement. But we don't have like the actual movements. And we also have already the calculation to see, okay, what the angle of the model should be. Feel free to copy this code, by the way in your own projects, if you wish. This is what we're starting with. So, let's do the basic thing. Let's add some input here. Now the method that we want is what we want to do is check if I'm pressing, let's use WASD. So, W, S, D, classic Doom style. So, let's just see if w is pressed, let's move forward. If s is pressed, let's move backwards. Simple stuff like that. The way that we do that is we just do, we must check if, Play Canvas noticed that the key is pressed. What we must do is this.app. Now, this.app in JavaScript, in the scripts here, is referencing the Play Canvas application, so, the raw Play Canvas stuff that you can query stuff about. Now, this, if you're not too familiar with JavaScript, this is whatever context you're currently running. In this case, this will be the instance of this player controller. So, you have this.app. Then, we'll do keyboard. As you can see, we have a syntax highlighting, and we have a heavy telesense as well. So, very useful to see. Okay, so, this.keyboard.isPressed. And then, if you do command shift space, you can also see, also, like the some controller, some autocomplete there. So, you have the isPressed. So, key codes, key to test, so, the key underline something, right? So, what we want is to reference, like the PC, for instance,.key. Underline w. So, this is checking if the w.key is pressed. So, this will. And since we're running on every frame. Every frame that the w.key is pressed, this, whatever is here will happen. And what we want to do, is we want to increase. We want to say that on x, we'll move one. So, let's use like, one as a uniform thing. So, if w is true, we'll increase x. And now let's just copy this code over, and do the s, which is for behind. So, let's just change key w to key s. But now we need to go the other way around. So, we do x minus equals one. This also means that if you press w and s at the same time, it will stay still. Because you're adding one and then removing one. I think it makes sense. And then, let's copy that again, now for a. Oh no, sorry, hang on. w should be on z, sorry not on x. So, w and s should be on z. So, this will work better. So, w means z plus one. s means zero minus one. And then, a means x plus one. Yep. And then, d will mean x minus one. Now, this will work well with the setup that we currently have. So, just trust these numbers for now. Cool, right. So, now, if you save that, so, command s to save that. Um, if we go back now to the editor, we need to, um, no, no, sorry. While we're still here, one thing that we'll need to do is, um, we are applying this movement to our rigid body with the apply force method. Now, the apply force applies, like, a method applies an immediate force on that frame, on the rigid body that we might need to scale up or down. Um, because, uh, you know, like, maybe it's moving too slow or too fast. We're just using one but you might need to, um, to scale that up.

16. Adding Power Attribute to Player Controller

Short description:

We added a power attribute to the player controller class, allowing us to change the scaling of the force without modifying the code. By setting the type of the attribute as a number, we can use both floats and ints. After saving the attribute, we need to click the parse button in the editor to update the attributes. The power attribute has a value of 4,500,000, which affects the skidding of the movement. Multiplying the movement vector by the power attribute allows for dynamic movement. With these changes, the player can now move around the scene.

And in order to do that we'll need to add a parameter for that. So let's add an attribute to the player controller now. Uh, what an attribute will do is the following. Now if you go back to the editor, we select our player, let's attach this script to the entity. The way we do that is we select the player entity, add component, we get a script. With the script, um, it's here on the bottom. Now you can, um, you can select whatever script that you want, that you already have created, and, and add this behavior to it. So here you just click and you select the player controller. Once we do that, we have the player controller attached there, which means that, okay, it will work, it will do stuff. But again, we will need to do that that that scaling of the of the force. We will do that is the following. Oh, by the way, you can click create and click here on edit to quickly to quickly edit that script. It was already open, so it's just one up. But here we go. Um, so what we'll need to do is create a new attribute for it so that we can like, we don't need to go back to the code to change that number. So what we'll do is we're going to say player controller, which again is the name of our class, right? But attributes, so the attributes of this class, I'm going to add a new one. We're going to call that power. If you just add this, you need to give it a type. The way that we do type is like this. So it already gives a nice documentation here. So you can you need to open and close brackets and you say type. And then as a stream, you give it a number. Now in JavaScript, if you're not too familiar with JavaScript, it doesn't have the concept of an integer or a float, it's just a number. So if you do float, this won't work. If you do int, it won't work as well. So we need to use the number, which encompasses both floats and ints. Now, internally it doesn't, like it does like know what type it is, you know, et cetera, you can like round it, et cetera, get a nice round integer, but the type is a number. So again, playerController.attributes.addPower. And then you give a type and we'll call it number. Now if we save that and then go back to the editor, it's not there, where is our power? Where is our power? You need to click on this parse button right here, which will reprocess that file, well, reparse that file and check for any attributes that you added. So now here it is. So now we have Power number there. So anytime that you change the attributes, change the defaults or whatever, be sure to click on the parse, at least once on that script to update what the editor knows that the attributes are. And the nice number four here is a huge number, so that's why it was important. So this one is the 4,500,000. So four five zero zero zero zero, so four zeros. And this is important for the reasons of the, you know, the, how much skidding we want and et cetera. So you play around with these numbers if you want. Now, if you press play again, 45, four zeros if you press play here, okay, we have it there. And then if you use was, right? It's not a running, right. We might need to check what's going on, right? Let's see. Let's see. All right. If we check back our code, we created the power attribute, but we're not using it anywhere, right. It's not on the notes that I needed to add it there. Sorry. So we need to use, actually, the power attribute that you just created on our code. So here on line 37, if you're using the same to be on line 37, so it's called movement here what we're doing here is we're creating a Vec3, right. We're defining our movement vector. We're normalizing it and then we're scaling it. Currently, we're only scaling it to dt again. So it's a performance frame. It kind of makes sense. But what we need to do is we'll need to multiply that with power. So just on dt here, just say, times this dot power. Now, again, this will be about the instance of the script and power will be exactly this value right here, which in this case will be 4,500,000. I think that's correct. Now, if we just refresh this, pick up the new thing. Oh, there we go. So now we're moving around, right? As you can see, it's not really rotating too much and have no animation. So we'll fix that in a second. But OK. We're moving, right? Interesting as well as you can– OK, this is this one actually. If you do like this, it's kind of like it's spinning around. OK, I like that. Anyway, OK. We have some basic interactions there. Moving on though.

17. Setting Model Rotation and Adding Animation

Short description:

To set the rotation of the model, we need to move the model entity, not the rigid body. We create a new attribute called 'model' in the script and reference the model entity as its value. We use the 'setEulerAngles' method to rotate the model on the y-axis. After saving and refreshing, the model rotates. Next, we create an animation state graph for the idle and run animations. The state graph editor allows us to define the starting node, nodes for idle and run states, and transitions between them based on conditions. The idle state is the default animation, and the run state loops. We add transitions from idle to run and from run to idle based on the speed of the character.

OK. Now, the next thing you want is to set actually the rotation of the model, right? Because otherwise it's just like– just like doing like this, right? Now, the way that we'll want to do that is we don't want to– we don't want to rotate the rigid body itself. Otherwise, it will like– it will bug up the rotations of the– that the calculation of the physics. So what we want is actually just to move the model. Just the model, not the not the rigid body. So for that, we will need on the script a reference to the model entity, which is the child of the player. It's only to this one. And the way that we do that is we'll just add a new– this zoom thing is getting in the way– we'll just need to create a new attribute for it. So here, let's create a new attribute. PlayerController.attributes.add. So create a new attribute. Let's call it a model. Then for the type, so now this won't be a number. This will be an entity. So now, we're referencing another entity. And then before we go back to the editor, let's actually add the code for that. So again, it's a new attribute. You can call it whatever you want, but the important thing is of type entity. And then here on the line 43, at least for me, we have to do set rotation to model. Let's remove that because now we can do it. And then let's do this.model entity which is what the entity that we're referring. And we'll do set Euler angles. That's how you call it, I think it is. Now for rotations, Play Canvas does use quaternions for rotation, but it's very complicated if you want to set quaternions yourself. So it uses four dimension rotations to prevent gimbal lock. A lot of explanation for nothing, but we need to use set Euler angles, not set rotation. If you do set rotation, you'll be using the quaternions, which we don't want, so using set Euler angles and you want to rotate on y. But I already added here the calculation for depth. We don't need to write it by hand. So just do zero for x. So we don't want to do anything on x. We want to use new angle for y and you want to use zero for z as well. Now, if we save that, we go back to our launch tab and then we refresh. Oh, okay. So you can see that very useful. It's already giving us some errors, which is very useful for us to debug, but it it says here, cannot read properties of null reading set Euler angles. Interesting. Let's go back here on the code so it's trying to read set Euler angles from null. How does this mean? So model entities is nulled. Of course, because we forgot to link them. If I go back to character, to player here, which has the script, I'll need to press the parse again. And now we have the model entity, actually right here, right? So then what we do is we click on the character medium and just drag it there. So now we have a reference here to the character medium entity from our script. So if we click there, we can easily see where it is. It also highlights there. Okay, there you go. Nice. Okay. Now you can refresh here. There we go. Right. So now it rotates. Now it's very sudden, the rotation, but you know, we won't have time to, to fix that, to make a nice rotation. I'll give, I'll leave you guys a, as a homework to, to fix that. Or you can just check how we did it on the, on the full project later. But, okay. This works for now. Let's, let's move on. Let's make some animation perhaps now. Cause that's fun. Cause again like now we're only on typos and not, not really goes happens, but let's add some, some animation.

Cool. Now if you go here on food, food random character on the animation folder, we already have idle and run. So those are two, again, two FBX files that, again, I just drag and drop from, from can you download? That's it. This is what it provided me here. Like I was ready to generate all those files for me. But what I'll need to do first is create a state graph for it, which defines like, oh, I'm idle or I'm running. And then how to, you know how to do that. So to do that, let's select character animation and let's create a new, an instant graph. So again, on assets now, so now we're creating a new asset, which will be an animation state graph. So new asset and instant graph. Let's call it character graph. Now, if we double click on it, we'll change gears on the editor to the animation state graph editor. Now, if any of you guys have used other game engines before, this is very similar to other solutions in terms of how to set up an animation state graph. The way that it works is that you have a starting node and then you have nodes and transitions between them based on conditions. In our case here, we've already created the boilerplate simplest one, which has an initial state, which currently does nothing. It's looping. It's a state with no animation attached. What we'll do is let's rename this one to idle, so the default animation... By default, you're idling, like breathing, just kind of like this. And then let's create a new node. Sorry, new state... And let's call it to run. So we can jump between idle or run states. The run state will also be looping, because it'll be doing like this, right? Let's make sure that we click on loop there. And let's add a transition from one to the other. There's a condition that will make it so from idle, we'll start running... And then if we stop running, the speed is zero, we'll go back to idle. So right click on idle, add transition to run. Same thing around, add transition to idle.

18. Creating Animation State Graph

Short description:

To create the animation state graph, add a parameter for the player's speed and set conditions for transitioning between idle and run states. Assign the state graph to the player model and link the idle and run animation clips. Set the speed parameter to 1.22 for a running animation. Apply the changes to the player template and adjust the speed parameter according to the player's actual speed.

Now, if we just do this, it'll just be coming back and forth and nothing will happen. So we'll need to add a parameter so that we can let the graph know what state, you know, what is the speed of the player so that we can actually move around. So here on the left, you can create a new parameter. So parameters, parameter, and let's call it speed. You can call it whatever you want and you can provide whatever type you want as well. So you have integer, so you can force it into integer, floats, boolean, so true or false or a trigger. A trigger will be true only for one frame on the first one and then it will go back to false. Very useful for like shooting where something happens only once. In our case, we want the float. That's our floating number, which will give us a number of what is the speed? What's like the magnitude of the speed vector that you're moving around. So with the speed parameter, we can select now our conditions and then let me just expand this a bit. And then here, I can add the condition. So on idle, I only want it to go to run if the speed condition is more than 0.1. So 0.1 works fine in this case. We want exit time to be nothing. So just erase exit time. Exit time means that it will only do the check once the animation is done, but actually we want it to be able to interrupt the animation. So if you're in the middle of your idle and you start running, you'll like stop idling and start running immediately. So be sure to erase exit time there. For duration, you can add anything you want. Duration just blends between the two states as the transition goes instead of just jumping from one to the other. This is the normalized time based on the speed, based on the time of the animation. So 0.2 is a fine number, just gives like some small blending. Let's do the same thing on the other one then. From run back to idle, that's at a condition, but we'll only do that if the run is less than 0.1. So if it went to zero, a very small number, probably it's not running so it'll go back to idle. Again make sure to delete exit time. Exit time shouldn't be zero. Exit time should be blank, just erase that. And then duration again, let's do 0.2 or whatever. Cool, that's it actually. That's the setup that we need for the animation state graph. Now when you create the state graph, you don't assign animations yet. We'll assign them in a second. This is only defining the raw behavior, just the brain of it. But the actual actions will be fine soon. So if you click here, then on the previous selection, or if you press escape, you'll go back to the main PlayCanvas editor. Now we have our graph here. What we want is to apply that animation to our model. So if you go back here to player and then select character medium here, we need to add that component for the animation. So let's add a component, anim. So it should be the first one, not this one, anim. And then just drag in the state graph that you just created. Just drag it in. And now here, as you can see, the idle and run states that we created. Now there are some slots for the actual animation clips for us to link, for us to attach. Before we do that, though, make sure that on the speed, you put that to 1.22, because from the test that I was running, this is a good number for... Like it kind of looks like it's running across the board. Looks pretty cool. So again, 1.22 should be fine. And then on root bone, select the root entity here. So if you just expand character medium, so be sure to use root bone there. This is just to make sure that the... This is a little bit technical on how animations work, but this is just to be sure that the animation and your entities on the scene are referencing actually the same transforms. This is how you make sure that everything lines up properly. Just a nice thing to do. And then here on idle and run, let's assign the animation clips. Now, if you open here idle... Actually, sorry, we'll need to make sure to select. So select character graph, sorry, select the character medium here to be sure to select, to have the slots here. So select character medium on your hierarchy and then from here, we'll need to select those clips. So you see, it's kind of like a placard thing from the movies. What's the name of that plaque? I don't know. So we need to select in this case, it's rootidle.glb. So just drag that into the idle. If you're not sure which one to use, that's a very nice way to preview, which is just by clicking on it. If you click here, you see, okay, like this is just kind of standing still. There's a character here. But in this one, okay, there's a nice animation here. So this only shows the wire frame view, but you can check what actually goes on like this. This looks like an idle animation. So this is what we want. So I just dragged in that one here and then same thing for run. So I just select the run folder and I want the root.run.glb. Just drag that in. Again, it's the file that has the movie thing. And if you're not sure, just select. Okay, this is a nice running animation. Okay, cool. Cool. Now we made some changes there. Let's be sure to apply that to our template, right? So here on the player template, make sure to apply all. That it applies to our template. Okay, you just click twice there. Now if I just press play here. Okay, so it's no longer on T pose. That's good. So it's using the idle animation but we are not changing the speed number. So even if we're moving about it, the animation state graph still things that were idling. So we need to make sure to set the speed parameter according to the actual speed that the player is going at.

19. Animating the Model and Handling Collisions

Short description:

To reference the animation component on the model entity, we use this.modelEntity.anim. By setting the speed attribute to the magnitude of the linear velocity vector, the animation reflects the player's movement. To add functionality when the player collides with a collectible, we create a script called collectibles controller. This script listens for the triggerEnter event on the collision component and provides a callback function to handle the event. In the callback function, we use this.entity.destroy to make the collectible disappear.

And the way that we do that is if you open up the editor. So there's a nice to do animation here. What we need to do is we need to somehow reference the animation component on the model, right, on the entity and then set the parameter. Now we already have this setup, right, the model entity. And if we look at our setup, the model... Sorry, the animation is on the same entity as the model. So we can just reference the character medium and get the animation component out of it, right? The anim component out of it. So that's very handy. So again, model entity, right? So, or whatever you call it here. So if you go this.modelEntity, which again is referencing the the same entity that has the animation. And you say.anim. So now we're referencing the anim component of that entity. And then we do setFloat. Now setFloat, you need to specify two things. First, you need the attribute name, so we call it speed. And the actual number, right? Now the number, we could... Like the easiest way is just to use the actual number that the Rigidbody is using. Like if it's applying force and then sometimes it's hitting, blah, blah... We want the actual number that the Rigidbody is using. And the the key for that is this.entity.rigidbody. So with this, we got the reference to the Rigidbody. And then we want the linear velocity, which again is... So that is the velocity on the X and Y and Z-axis. Not the rotation, so how much it's actually moving. But this is a Vec3, so this is like an actual three-dimensional thing. But we want like the length of it, right? We want the magnitude, how much it's actually moving. So we can just say,.length, which is an average. And also you can just check the view reference for that. So with this, we're getting the magnitude of the linear velocity vector and passing that into our animation. So if we save that, go back to the game. We have to reload the scripts, because the scripts are already loaded. And then we move. Nice! Now what happens if I keep pressing D to move to the right and then I hit that collision right there? Let's see what happens. Oh, it stopped because it's using the actual rigidbody. It doesn't look like the classic thing in video games where the character is like running against the wall like that. This actually makes a little bit more sense, which is pretty cool. We got that out of the box. Cool. All right, so now we have some very nice integration here now.

Now, if we take this player and we go over the apple here, nothing happens, because we didn't add anything to do that. So let's add that. Let's add a trigger so that when a player goes over the collectible, it does something. Going back to the editor here, let's select our food. So we'll need to add a script for that, right? Let's add it here on collectibles. Let's create a new folder. Let's call it scripts. Then within the scripts folder in the collectibles, let's call it collectibles controller. This is what I mentioned, that we'll be creating some new scripts rather than just using the script templates, right? This is the only script that we'll be creating from scratch. But this is interesting because if we create a new script and just edit that, this is what every new PlayCanvas script comes with, right? So it already contains the boilerplate code of creating and attaching a PC, which is like a PlayCanvas script, and we already have the initialize method and an update method. Now this is a topic for another workshop about hot swapping, hot reloading. So I'll leave it to you guys to take a look at later. I'll just remove this because we won't need it. And also we were moving the update method. We don't need the update method. What we need is some way to say whenever an entity, whenever a collider passes through this, like it was picked up, right, and we need to do something about that. So the way that we'll do that is since this script will be added to the same entity that has the collision, we just have to listen for an event on the collision. This is a very important topic on Play Canvas, which is events. Events in Play Canvas are fired and triggered by all the different components and it's all documented. But it's very important to understand that events drive the behavior of different things. What I mean by that is the collision component, for instance, every time that another collider enters through it or is still there, it fires an event. And if anyone is listening to that event, you can do stuff based on that. So you don't need to constantly keep checking has it collided, has it collided. You don't need to do that, you just need to subscribe to different events. And this is what we will be doing. We'll be subscribing to the event, I will call it attaching. We'll be attaching to the event on the collision component that says something entered this collider. The way that we do that is on the initialize method. So we'll attach right when the game starts. We'll say this.entity.collision. So with this, we are referencing the collision of the entity because this is the... Again, this is the collectable controller, this is the script itself. We're not talking about the script, we're talking about the entity in which the script is attached to. So this.entity.collision. So now we're talking about the collision. Now we'll attach to that event. And to attach we say."on". So that on, it literally means like whenever this happens on this event, let's do something. The name of the event is triggerEnter all lowercase all together. And again, this is all documented on play canvas, a reference about, what are the events that the collision triggers and how can I use them, etc. So whenever there's a trigger entry on this particular collision, we can provide a callback. Now callbacks in javascripts can be done by just referencing another function, or we can create one right here. So we can create a new function, an anonymous function, by doing the following syntax. So it's open and close brackets, because there's no, so this will have any parameter. And do equals more than, so an arrow. And you can provide any code that you want here. So this is the code, right. This is the function that will be called whenever the collider that's attached to this entity has a trigger, right. And what we'll do here is, so one thing it needs to disappear, right. So do this.entity.destroy. So it will disappear.

20. Creating Collectable Controller and Game Manager

Short description:

To create a collectable controller, we need to fire an event when a trigger occurs and destroy the collectible. We then add the collectable controller script to the food entity and apply it to the templates. A game manager entity is created to handle overall game functionality, including time management and event listening. The game manager script is already set up to work with the collectable controller. We also modify the spawn collectible code to reference the food template and dynamically instantiate it at the desired position.

But more than that, we needed to also we need to let the game know, oh, you picked up something. Now, the script templates that we have set up there are listening for events as well. So events can come from components, right. So for instance, the collision component, or we can fire our own events. So you can tell everyone on the scene, you can say everybody on the application, say, oh, by the way, this happened. And the way that we do this is say, this startup, so remember this startup is in reference to the PlayCanvas application. And say, that fire. So with this, we are firing an event. So that if anyone is listening to this particular event, such as we are listening to trigger event, trigger ends around the collision. They'll immediately receive that message. And we can say, collect it. So this is the name of the thing that we called. We can find more about it later. But if we just say this.app.fire, collect it, anything that is listening on this.app, so for instance, if they do this.app.collected, if they do this, they'll receive the message. Cool. So that's it. So this is the code that we need for the collectable controller. Whenever there's a trigger, we fire that event. And then we destroy it. Then what we do on the food here is then we need to add that script now. So then we go here, add component script. And then we add our new script called collectable controller. And then again, we need to apply, to make sure that we apply to the templates. And if you created more than one template, like have bananas and cakes, and you imported your own assets and you want to use, make sure to add those to the collectable controller, to all of that. And let's test it out. Press play. We're almost done with Phase Two, don't worry. And then I walk over there to the Apple. Oh, cool. Right. It disappeared. Nothing else happened because we didn't do anything else. So currently our game is walk towards the Apple. Cool. Right. Nothing happened. So let's move on right now. Cool. Now, what we want now is to use now the script templates that we have here. Right. Because again, it contains like boilerplate code for the actual like gameplay that you're free to look at later, copy and make it your own. But what we'll need to do is we'll need to create a game manager. So we have a game manager entity. Let's create on root. Let's create a game manager. It's called game manager. Script and let's add the game manager script. Which again, is already there, right? Let's take a look at what this game manager is doing. Make sure to click on parse by the way, because it has some some settings there. So if you open the game manager script, it already has a bunch of stuff that I won't have time to go through here. But it basically does stuff like, oh, am I playing around is the round over the stuff like counting the time and so on, for instance, are in the update method. It decreases time as time passes and then it fires an event. When the time s Up and etc. Now, this game manager already contains, like, most of the code that we need to make it work. And if you remember, it's already listening to the collected event that we just created on our collectors on our collectible controller. Yeah, so as you can see, we're already attaching to this event. So the game manager will work flawlessly with the collectible controller that just created. So, okay, we're good to go. So now the game manager is receiving the message as you want now game, by the way. Game Manager is an interesting name to give to exactly this is the script that doesn't handle anything. Any particular like entity or thing in your game? It just handles like your overall thing, right? Okay, I collected something. The players over there, I'm starting a new game. I'm restarting the game. I just seen here. And if we do a command F or control F to do, there's one thing left, which is on the spawn collectible. Now the spawn collectible already has some code here, which is basically what it basically does is it looks for a random position on the board for a place that doesn't have an obstacle on it. So this is already implemented for us. You can take a look, take a look here today to how it's implemented. You can make it on your own. You can, you can copy it. But what it's not doing, is it's not spawning. So if you play this and check it out, it will not spawn anything. We need to add that functionality ourselves because I want to show you guys how to do that. I mean, it already, at this point, at line 92, we all ready have the new X and new z, which is exactly which position we want to, we want to spawn but we need to do that. Now, in order to do that, first we need a reference to the templates that we created. And this is why I wanted to create a template out of the food items that you created. Right so, for instance, the apple writer, we have is an empty is a template that we saved here, food, right? So what we want is on the game engine we'll add an attribute so that we can reference that template and then we can dynamically instantiate it, you know, as we pick up stuff. So what we'll do is we'll say GameManager because now it's a GameManagerScript.attributes.add and let's call it a food template. And then for type, it's not number, it will be an asset. Now instead of again, so this means that we're not going to reference anything that's on the scene right now. We're going to reference something that is on the project asset. Now we don't want to reference any asset, you cannot instantiate a texture, but you can only instantiate a template. So we're going to say that the asset type is template. So this means that food template can can only accept references of type asset, which are templates. So you're sure that it's only template. By the way, if you guys have created like more than one, if you created multiple food templates, you have banana, you have apple, et cetera, you can say, and the arguments, you can say array equals true. If you do array true, this means that you can set more than one food template, and then food template will become an array, and you can do like dot length to see how many were added, or you can reference with the quotients thing. In our example, there's only one, so we'll keep it without the array thing. Then, what we'll do, so I have food template here, let's go back here to the spawn new collectable position. What we'll do is we're going to say, we're going to say this dot food template, right, dot resource dot instantiate, oh, sorry, instantiate.

21. Phase Three: User Interface and Publishing

Short description:

We instantiate a new entity from the template using the 'dot resource dot instantiate' API. Then, we set the position of the new entity and add it to the scene hierarchy. We can use Chrome dev tools to inspect and debug our code, add breakpoints, and check variables. The console and network tab are powerful tools for debugging and monitoring file downloads. In phase three, we'll focus on user interface and publishing. Let's continue from where we are and work on the UI.

Now, we need to do dot resource because we want the actual raw template from it, like the actual data that contains from the asset reference, and then we want to instantiate that, so this is the API to do that, so dot resource dot instantiate. This will create a new entity, which is a copy of that template.

Now, we want to do stuff with it, we want to move it where we want, so let's reference it somewhere. So let's say const new entity equals the instantiate, and let's say new entity dot set position and UX0 do that. So now we're going to position the new entity that we just created to that position that we already found before, right? The code's already done.

But if we just do that, we create a new entity, but it's not added to the scene yet, actually. We need to actually make it a part of the scene, otherwise it's hidden away and it'll be deleted afterwards. So we need to add it somewhere. We need to add it to the hierarchy. Let's just add it as a child of the current entity. So let's say this dot entity dot add child, new entity. There you go. Now, with this, we are creating a new entity, which is instantiation of the template, setting the position and then adding it to the scene. Now, if we press play on this, now, oh, no, on the game manager, we need to parse the script and you need to reference our template here. So wherever you saved the food template, just reference it there. If you set up everything correctly, you should be able to like, it will highlight and we'll be able to like simply drag and drop there. Now, play here. If you press play here. Okay. We're able to walk around, right? So this is all working, but then when we pick this up, it will send a message to game manager. Game manager will then it will be destroyed and the game manager will spawn a new one. So it spawned one right there. So if I picked it up, okay. Now I spawned one there. So you can see how the game is like almost ready, right? Like we're moving forward, right? Now one quick thing that I want to talk about, it's very important. So this is the last part of a phase two, phase three will be pretty quick. Then if you can open Chrome dev tools by going to, to, to view. Yeah. So on view, if you're using Chrome, so view developer JavaScript console, and then from here, you can check anything that happens in your code and you can add the bug points like as you go. So if you see here on sources and you open API assets files, you can see that here we have the exact same hierarchy that we have on the editor. So we have food run script templates. All the scripts are here in the exact same photo structure. So if you want to see what's going on on player controller, let's say that we have a bug there. Well, I want to have, I want to know what's going on there. You can inspect the code, make sure that the code is correct. And you can just edit the book point. And then this will happen only when I press W. So let's press W. Okay. So it stopped. So it wasn't break point. And we can check what is DT value? You know what section is that? What is, which keys are being pressed? You know, what's the state of our, of our entity? You can check everything right here from the bug tools. And you can just press again to continue. Let's, I was pressing W for, so let's, let's move there. Oh, okay. I fell out of the, out of the game world. Cool. Yeah. That is pretty cool. So, so out of the box things, things are here, right? It can also check on network tab. Exactly. What are the files that you downloaded? And you can use the console to do more stuff as well. So if you want to see, like if you want to do for instance, if you want to fire an event, you can do it by the way, you can use this.app.fire, right? Sorry, it's pc.app.fire. So you say, if I fire, if I fire the collected events, yeah, it just, it's on a new one because it thinks that the game manager thinks that something was collected but it didn't. So you can like do all sorts of crazy stuff here from the console and from sources. So it's a very powerful tool for you to debug stuff like out of the box. Cool. Okay. Finally we have, so this is phase three. Let's go back to the slides real quick. So, that was phase two. Sorry, we'll move on to phase three. Phase two was a big one. So we learned about creating using scripts. We learned about events. We learned about physics. We learned about animations. We learned about all sorts of crazy stuff. We just, I'm not sure how much we can do in the last five minutes but let's see how far we go. So let's move on to phase three. Now phase three, we also have the same setup as before that we have the project ready to go for phase three. Let me open that up. Let me send it to you guys. This is phase three. So again, if you got lost in any place and you want to continue from now on, just fork from this one and also send it on discord or you can just continue from where you are. So I'll be continuing from where we currently are because we're almost there. I think we won't have time to do audio. I think we might not have time to do that, but let's do the UI. Let's at least do the UI. Now for phase three, the idea is doing user interface, audio and publishing. I think we'll only do user interface and then publishing because I think user interface is pretty cool and we cannot really see what's going on there. We don't know if we're winning, if we're losing, the game is playing and we're not sure how much time we have left. So let's do that real quick. Let's see if we can do that on time.

22. Creating UI Screens and Elements

Short description:

In this part, we'll create actual UI screens for the game. We'll start by creating a 2D screen and adding a text element for the score. We'll customize the position and anchor of the text element. Next, we'll add an image element for the time bar and set up the anchors to match the size of the parent. We'll also customize the color of the image. Finally, we'll add a script to the 2D screen and make references to the game manager entity and the time bar entity.

Now what we'll do is let's create actual UI screens first. So if again, if you go back to, sorry this is very annoying. If you go back here to the example, the UI is basically, so you have this time thing right here, a score text. And if you remember when we lose, there's a big screen saying, oh, time up, you know, like round over and then a button to start again. So let's do that real quick. Let's see if we can do that on time. That would be challenging.

So onRoot let's create a new entity and we'll create a user interface. We'll create a 2D screen. Now, everything that you want to be on screen space, it needs to be under a 2D screen. Otherwise it will be like on the 3D world. So let's create a 2D screen. Since there's always screen space, you can move it up. So it's not like in the middle of your hierarchy there. So you can move it up wherever you want. It will always be in screen space. And let's add, let's start by adding a text which will be the score. So here, let's create a new user interface. Text element. Where is it? There. Now be sure to be, to face the right side there. If you don't see it, it's probably on the other side. Wait a minute. So when you create a new text element, it assigns already like a random font, not random, but like the first font that you have in your project. So on the food run, here we have a lot of interesting fonts already set up. So you chose the first one, Kenny Blocks, but we can choose anyone. Let's choose this one, whatever, Kenny Mini, Kenny Mini Squarer, yeah. So I chose this one. Again, just drag and drop. And then we can move it about wherever you want on the screen. Now, by default, the element will be anchored to the center of the screen, which means that if I play, let me do it like this. If I play text areas in the middle and I rotate like this, if I do anything on the screen, play on a mobile device, it will always be there on center of the screen, which might make sense if you're new to use case. But we want one that says, like they're on top left, right? So if it's on the top left, if you want things to be on top left, what we do is on text, we can set the anchor to be there. So we already have some presets here. So on preset, if you just press top left anchoring pivot, it will automatically set the pivot and the anchor to the top left. And then we can move it down like this or something. Let's call it score text, set score to right? Cool. So now we have the text ready for the script that will actually put the scores as we move along.

Now we're almost at time. If you guys are happy to continue, let's continue let's continue for now. If you guys need to drop in, then fine. But I think we can, let's go ahead for now, let's see how far we can go. I'll go as fast as again. But again, I think the recording will be available later as well. So you can take a look at that later. And also again, the full project will be available. Yes, we did start a few minutes fast. Let's see five minutes, what are you going to do Jorn? Let's see. And the full project again, will be available later if you guys take a look at like the full thing with a little bit more like breathing. So we have the score text. Now let's add this time right here, this bar, that's pretty neat. So the way that we'll do that is a following. We'll create a new entity as well, a new user interface. Let's call it an image element. So this image element. Let's also put the preset on the top left anchor, and keep it so it's there. By the way, this means then as we move stuff around, to always be on the top left there. So it's always there. Very useful for creating responsive UI for mobile devices that you can rotate or not. So yeah, this is a pretty neat feature. If you select here on the resize element component, you can easily resize the size thing. So let's create that background. So this is the background here, that white thing on the back end, on the background. And then let's create a new entity to be like the middle part, right? So now let's color this one the green tint that we have there. Now we want it to be like, to take the full size of the time, right? But then as the time goes on, it should go like this, right? Or like this for you guys. So the way that we do that is very easy to set up the anchors so that it's exactly, it matches the size of the parent. So we can match the size of the parent by setting the anchors to be all of the corners. So we can either select this gizmo right here and then go here, so this one should be here. This one should be there. This one should be there. And this means that the anchor is 0, 0, 1, 1. Now it has some margin, which we don't want. So it's taking more space. So let's reset up the margin there. So it's all zero. Now it's taking the full space, but if the margin then is decreasing like this, you can see this is the fact that we want. Like, as the time goes on, we want the margin to increase. So we have all the setup there that we need for make that happen now. Let's take the score here. Let's put it up there now. Now actually, this is everything that we need. Now, of course, we need to add the tag, the text says Simon, et cetera. Let's not do that. But what we'll do is on the 2D screen here, let's add a script and let's add the UI controller script. Now the UI controller script already has like all the code that we need to make all of this thing already set up properly, like exactly as we need. But we just need to make the references to the right entities. So the first one that we need, we need the game manager entity. So this is the entity which contains the game manager script, so let's put that. Now we need the timebar entity. So that's the green one.

23. Final Project and Publishing

Short description:

Let's check out the full project, which includes all the UI controllers and a final game setup. Feel free to use the CC0 assets by Kenny and add the proper credits. To publish to Play Canvas, click the 'publish/download' button, give it a name, and press 'publish now'. The resulting link is permanent and shareable. Play Canvas is playable on mobile and multi-platform. That's it for today. Thank you for joining and sorry for going over time.

Okay, cool. The score text entity. Cool, let's put that on there. Now if you remember here on the example there was a starting, there was that Eat Me there, string that was there. Let's skip it out for now. That's not created. On the round over screen entity and round start, so this is the game over ones, right. So let's not do anything on those right now, so otherwise it will, otherwise it will take too much time. But now if you press play on this and you check out what we just did, so let's do another one. Oh no, can I set properties of null, setting enable? Probably because I didn't set one of the things. Let's fix that. So this is very useful by the way, to have these things here. If you click on the button, it will automatically open up the code editor for you with syntax highlighting and highlighting exactly where it went wrong. So now it's using this, right. Let's check if this is not null then do the thing. Otherwise just let's check it. Let's save it. Refresh. Okay, now it only starts when you pick up something, right? So let's pick up some, let's see what happens. Oh, there we go. Okay, so now we have the scores. Now we can see that the time is going down. And then if you pick it up, it goes, oh yeah, okay. So now we would have lost. But again, we didn't finish setting up all the different stuff. Now if you wanted to see the full setup, all that you need to do, let's do that right now because you no longer have time. Let's now check out the full project. So again, I'll send it soon. Full projects. Let me send you on the chat. This is the full project that you can take a look and you can fork as well if you want. The final setup is basically just setting up all the different UI controllers that there and creating this screen right here, which has this button on the bottom, which already contains some hover pressed hints. So, as you press, as you go over, it does different things. And already has like the listener as well for when you click to restart. So, you have everything there that we need. And this is the full project. Again, go ahead guys, go crazy on it. You can take a look at everything that is done. Feel free to use, I mean, all the assets are CC0 by Kenny. Do give him a shout out if you use any of those. Do make sure to add the proper credits. And this is the final game. Let's see if you have anything else there on the slides. But I think that was it. So, yeah. So, we didn't learn how to use audio, but I think that's for the next one. Be sure to take a look at the audio manager script there. Be able to see exactly how it's done. And this is wrapped up. Oh, oh, oh, one final thing. If you want to publish to Play canvas, this is super important, on the toolbar here, the last toolbar here, publish slash download. Just click it. Publish to Play canvas. Give it a name. Give it a description. That's optional. Just the title is required. Press publish now. It's building. There it is. It's building up. Click. This is a permanent link to your particular build. This is yours forever. Never be taken away from it unless you download, unless you delete the project or delete the app. Otherwise, you can send this to everyone. You can send this to anyone to play around with your game. And also be sure to tweet. If you do it, be sure to tweet about it. I'll retweet it. We'll help each other out, we'll follow each other to help out those in game devs. Because again, this is playable for everyone. You can play it on mobile, you can play multi-platform. Out of the box, there you go. This is how you do publishing on Play Canvas. I took 30 seconds or something to do that. There we go. And yeah, that is Play Canvas. Thank you very much, sorry for running a little bit over time. I think I was a bit too optimistic when I was preparing this. I did practice it twice, I did manage to do it on time. But I think I spoke too much today.

Watch more workshops on topic

JSNation 2023JSNation 2023
116 min
Make a Game With PlayCanvas in 2 Hours
Featured WorkshopFree
In this workshop, we’ll build a game using the PlayCanvas WebGL engine from start to finish. From development to publishing, we’ll cover the most crucial features such as scripting, UI creation and much more.
Table of the content:- Introduction- Intro to PlayCanvas- What we will be building- Adding a character model and animation- Making the character move with scripts- 'Fake' running- Adding obstacles- Detecting collisions- Adding a score counter- Game over and restarting- Wrap up!- Questions
Workshop levelFamiliarity with game engines and game development aspects is recommended, but not required.
JS GameDev Summit 2022JS GameDev Summit 2022
86 min
Introduction to WebXR with Babylon.js
Workshop
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.

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

JS GameDev Summit 2022JS GameDev Summit 2022
33 min
Building Fun Experiments with WebXR & Babylon.js
Top Content
During this session, we’ll see a couple of demos of what you can do using WebXR, with Babylon.js. From VR audio experiments, to casual gaming in VR on an arcade machine up to more serious usage to create new ways of collaboration using either AR or VR, you should have a pretty good understanding of what you can do today.
Check the article as well to see the full content including code samples: article. 
React Summit 2023React Summit 2023
32 min
How Not to Build a Video Game
In this talk we'll delve into the art of creating something meaningful and fulfilling. Through the lens of my own journey of rediscovering my passion for coding and building a video game from the ground up with JavaScript and React, we will explore the trade-offs between easy solutions and fast performance. You will gain valuable insights into rapid prototyping, test infrastructure, and a range of CSS tricks that can be applied to both game development and your day-to-day work.