Complete guide: Action horror 3D game in Unity 2020 | Jan Jilecek | Skillshare

Playback Speed

  • 0.5x
  • 1x (Normal)
  • 1.25x
  • 1.5x
  • 2x

Complete guide: Action horror 3D game in Unity 2020

teacher avatar Jan Jilecek

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Watch this class and thousands more

Get unlimited access to every class
Taught by industry leaders & working professionals
Topics include illustration, design, photography, and more

Lessons in This Class

13 Lessons (4h 39m)
    • 1. Introduction

    • 2. Install Unity 2020 and Rider for C# development

    • 3. Animate your first 3D model: import animations, models and use unity asset store

    • 4. Code a basic 3D player controller: handle input, control animations from script

    • 5. Advanced animation states and gravity

    • 6. Add zombie enemy spawner and code simple artificial inteligence

    • 7. Code TELEKINESIS as a special power

    • 8. Zombie attacks, player health system, death animations and UI

    • 9. Enable CLOTH SIMULATION for the player's cape, use better models for the player

    • 10. Atmosphere: Model the terrain, paint trees and grass

    • 11. Design GUI elements, create a score system and win/lose scenarios

    • 12. Use sounds effects and create a sound system. (Optional: Add fog with AURA 2)

    • 13. Final build: Tweak the gameplay and the sounds of walking and build the game!

  • --
  • Beginner level
  • Intermediate level
  • Advanced level
  • All levels
  • Beg/Int level
  • Int/Adv level

Community Generated

The level is determined by a majority opinion of students who have reviewed this class. The teacher's recommendation is shown until at least 5 student responses are collected.





About This Class

Hi, my name is Jan Jileček and I am a professional game developer with master's degree in computer science and I've been developing games since 2011.  My most well known game is Jung's Labyrinth, a kind of a psychological exploration game, developed in Unity.

We will go through everything you need to create a mature 3D game, where you have the special power of telekinesis to defend yourself against hordes of enemies. I will take you through every step of the creation process and we will create the game together from scratch.

This course will teach you how to:

Prepare your environment

  • Install Unity 2020 and Rider for C# development

  • Set up your game development environment

Create your first game

  • Use Unity Asset store

  • Import 3D models from Sketchfab

  • Import animations from Mixamo

  • Control animations from a script

  • Handle input controls

  • Code a basic 3D player controller

  • Implement gravity

Design gameplay and add special powers

  • Add zombie enemies

  • Code enemy spawner

  • Code basic enemy AI

  • Code a health system for the player

  • Code TELEKINESIS as a special power

Tweak the game to look amazing

  • Use sound effects and create a sound system

  • Model the terrain, paint trees and grass

  • Add atmosphere with the lighting system

  • Enable CLOTH SIMULATION for the player's cape

  • Design GUI elements for health etc.

  • Import extra fonts, sounds and music

  • Create a score system, win and lose scenarios

  • (Optional) AURA 2: Add fog and volumetric light

and finally build the game into an executable and have some fun with it!

Meet Your Teacher

Teacher Profile Image

Jan Jilecek


I am a Czech game developer with master's degree in Computer Science (focus on Computer Security/hacking). I started developing games in 2011 in Java LWJGL and then moved on to Unity in the later years. My most well-known game is Jung's Labyrinth, a psychological exploration game that uses Jungian archetypes to guide your through the individuation process.

I like BJJ, Jungian psychology, mythology, dystopia, existentialism and psychological horror movies.

See full profile

Class Ratings

Expectations Met?
  • Exceeded!
  • Yes
  • Somewhat
  • Not really
Reviews Archive

In October 2018, we updated our review system to improve the way we collect feedback. Below are the reviews written before that update.

Why Join Skillshare?

Take award-winning Skillshare Original Classes

Each class has short lessons, hands-on projects

Your membership supports Skillshare teachers

Learn From Anywhere

Take classes on the go with the Skillshare app. Stream or download to watch on the plane, the subway, or wherever you learn best.


1. Introduction: Hi, my name is any electric and I'm a professional game level appropriate master's degree in computer science, and I've been developing games since 2011. My most well-known game is humans Labyrinth. I kind of up psychological exploration game developed in unity. We will be making the game in the background. Take you through every step of the iteration process. And we've got to create the game together from scratch. Firstly, go install Unity, Download, and then import animations. We will quote a simple 3D Character Controller. We will implement gravity. Then we'll import models from the Unity Asset Store and move on to coding basic artificial intelligence and enemy spawner. Then we will implement a special power that like a nice is that it's manipulating objects in the scene I'm in your mind and drawing them similar to games like control or BioShock. We also need some blood spot effects. So you'll use particle systems for that. Then we will implement enemy attacks and a buyer or death. We will start changing the models to better ones. And the main curve that also needs a cape, we will use quad stimulation for that. Next, we will model the terrain. We will obtain the mountains, grass, and trees. We will also add more buildings and NMR. 2. Install Unity 2020 and Rider for C# development: The first thing we need to do is to install unit itself. So go to Google and search, download Unity. Click the first link, and then click Download in the hub. You install it like you would any other software. And after it installs, you open it and it will install a default version of Unity. I think the latest one is 2020, point to. And if it doesn't install it, just click Add and install it manually. You can choose whichever version you want. But we will be using the latest one. We will not be using any version specific features. So don't worry, if you install the wrong version. And that's it for unity. Next, you need some development and environment. For that we are going to be using writer by JetBrains. So go to Google and search writer and click the first link again. And I'm not executable file. After installing the rider, it will ask you to customize it. So do that and how to customize it. You will be all set for starting this game development course. See you in the next lesson. 3. Animate your first 3D model: import animations, models and use unity asset store: Welcome to my Game Development Series. My name is cn, and in this part, I'm going to show you how to animate a 3D character. First, we're going to create a new project by clicking on New and choosing the 2020 point 2, 1. Let's call the project tutorial. And click Create. Let's wait for the project to load all the necessary files. Okay, so this is the default layout. We want to see the scene and the game at the same time. So just grab the game window and put it here. Left window, the cmd window is 430 manipulation. And right window shows the camera projection. The last panel here, the hierarchy, is used to create all your game objects and keep them, give them in order. And the right bundle here is used for configuration. And you can find the imported sources, modulus, animations, sounds, etc. In the bottom panel here. First I create a new game object plane. Object plane. Let's go to Insert. We're animals change d by frame to shade it. That's going to create a 2D plane. You can move around in this window by holding the right mouse button and pressing the W a is the and flying around. If you fly too slow, just click this camera configuration and change the speed to something higher. Okay. So that's it for the movement in the scene. Let's what's called this object floor. Because this is the object that our character is going to be standing on. And let's load some three characters into the scene by going to Window asset store. And here you can actually, this is going to open your default browser. I'm using Chrome for this tutorial. So at just the to us it's story And search for polygon started back. There is multiple polygon bugs, the urn which are obeyed. We are looking forward to start at back. And let's sorted by brace. Should, shouldn't be free air. This is the one polygon started buck. You click this button to my assets, and it's going to get automatically added to your assets. So now you can actually go to the Package Manager, Blake, my assets. Search for it here. And here it is. Now just the click Download. I already have it downloaded and import. This contains all sorts of demo objects like trees, characters, and and so on. Import. Now, after it's imported, I'm going to create a new empty object by right-clicking here. You can create empty. And this object, it will be a parent object that will hold the 2D character. Let's click here and reset. That's going to set the position of the object to the middle, to the absolute center of the scene. It wasn't there before. Then we are going to import our 3D object of the character. Let's go to polygon starter, brief apps, characters, and import either the guy or the girl. I'm going to go with the guy. Either a drug it into a program, into the scene, or again here and burn to the parent object. Name him to layer. And see he's nice list snapped to the floor already. So the next thing we want to do is to make him animate it. We are going to colder the movement controller later. Right now. I want to do just something fun to show you how easy it is to animate the character. Let's go to mix some of that com, which is a site of weight, various animations for the, for the 3D characters. And those are free animations. All we have to do is just login here. And I'm just going to log in here with my Gmail account. Okay. I'm logged in. And let's go with the break dance, so it's fun. We will import the walk animation later anyway, and we will coat the working. So let's just go with this one. Just looks cool. Click, click, click, Download. Leave the default options. Okay, So after downloading the animation, we want to import it into our project. Let's create a new folder for it here. Right-click Create Folder. I'm going to name it animations, underscore animations. So we can find our folders more easily. As the project gets bigger. There's going to be more folders that are named with normal common case. I'll just use underscore notation, naming convention for our folders so we can orient easily in our project structure later on. So underscore animations, open it, drag the FBX file in there, and go to it. Animation. And we want to change it. Do you want to change it? Do humanoid click to rake humanoid. Apply. And we will do animation. And let's click Loop time and rename it to do break down. Yes, and click Apply. Then we go to the player. We can see the animator component is already attached, but it contains no controller. So we have to create a new one. Right-click, create an Animator Controller. Let's call it player controller. Double-click it, and then just drag the animation inside. For some reason it's called somehow instead of instead of break dance. Let's see. Oh yeah. That didn't get applied. The name break dance. Apply. Apply now. Okay. Now it's saved. So the animation gets applied as the first animation after the entropy entry point and the transition is default. And we want to loop the animation. So let's go. Yeah, it's the Bose is looping. Good, good. So the last thing we need to do is to associate the animator controller, which are created by a controller. You do that by either dragging it there for you can click this circle and choose by a controller. Now, when we run the scene and V, and again, the character should start the animation. So he should start dancing. Let's see. Yeah, our guy is dancing. And that's how easy it is to actually animate your character. In the next part, we're going to make our character walk and react to our controls. We're going to go to our simple 2D character controller. So that's it for now. And see you in the next part. 4. Code a basic 3D player controller: handle input, control animations from script: Welcome to the next part, where we are going to be creating a 3D Character Controller. From scratch. We are going to actually go to the behavior and map it to the animation. The first thing we will do is to assign a camera behind the shorter of our characters. So it looks like it's the third person of you. Wrap the camera and assign it to D parent. And we actually want to move the camera right here where we are looking. You did it by clicking the main camera GameObject and align with you. And it's going to move the camera right to the view that to be set up with the NC movement. So that's it. Now when I move the corrector of the Communists going to move with it doesn't look like it's moving because there are no objects around. Solar, just add some more objects so they're seen as more dynamic. But first let's make it that Blaine bigger order floor, as we named it. Click the floor. And let's change this scale. I'm here to do something like that on all three axes. And we can either flex treat. But let's leave that for later. Right now let's import some models from the brief abstract or from the starter package. So I see there's a car, let's grab it. Just put it here. And the house saw a steak house. But it's somewhere. And some more objects like a crate. All right, so now when we move the layer, we can actually see it's moving. Good. Solids. Move on to the scripting. Create a folder, name it, underscore scripts. Go to create C-sharp script. And let's call it player controller. You may need to set the default development environment, the rider. And you do that by going to Edit references, External Tools. And you choose the external script editor to Rider. And now when you double-click it, the script is going to open. In the rider that we installed previously. You can of course use any development animal mentally you like Visual Studio or whatever else. I prefer a writer. So this is, I'm gonna make it bigger for you. This is the classic structure of the script. It inherits these behaviors from the amount of behavior. So these functions are not needed. Now let's delete them. First. We're going to need a character controller, and that will provide the interface to move the model around. So let's create a variable for it. Character controller is going to be public character controller, character controller. And we are going to be using a variable force speed that's going to control the speed of the character. And let's create the move method is going to be private. And we'll be here. And it's called the move method. And the movement that holds all the logic for controlling the character is going to be a few lines of code. It's pretty easy. We need the horizontal and vertical axes of the input, which is basically gamepad steaks or the keyboard. Whatever controller you use, unit is going to take care of that. So we need horizontal and vertical. So let's create two variables for this. Horizontal and vertical moves. Input dot get axis and vertical ones. And now we need actual vector that's going to hold the movement information that we're going to pass to the character controller. It's simple multiplication of the direction vectors with these horizontal and vertical vectors. We do that like this. Transform got forward multiplied by vertiginous plus transform the right multiplied by horizontals. And we're going to pass that to the correct controller. And we're going to use the speed that we specified earlier multiplied by time, delta time. This right here is time between the frames, which will ensure character moves the same speed dependent on the frame rate in moose. Same way on 30 FBS and 60 FPS. And we multiply that by the vector we created. All right, let's save that. Let's go back to the Unity editor. Go to player, Add Component, character controller. And that's going to create a capsule. Around the model. And we want to make sure the capsule, the capsule touches the ground. Because we're going to be implementing gravity lighter. So we want the player to fall on his feet. Right now, he would fall to his waist. So let's make the center higher. It's actually one, exactly one. And the rest of the collider and looks fine. We're not going to be making any complex collision system so that the lines here is okay. But if you are comfortable with making it more precise, there is no problem in making derived radius smaller. And the hate a bit smaller. And moving down a bit. Surely for this right here, we want to use the asymmetric view. You do that by clicking the cube right here. You switch between Perspective View and isometric view. Looks like the glider is there for the right value for it. Okay? So now all we have to do is to assign the play controller to the parent object and assign the character controller player do it. So the information gets passed down to it. And now when we run the game, the daybreak density emissions going to play, which is going to look a bit weird. We're going to change it, do the walking animation right away. But let's just try it out. And now I'm going to press a mitosis. We are cameras should move with it. Actually, let's copy this component. Can move it from here and with up to the parent based company that's new. Right. And now it's going to work. Okay. Okay, I'm pressing WASD and we're moving around. Now let's change the animation to walking. Let's just search for some walking animation. It looks fine. Let's click in place. Download, download. Okay. So our walking animation. Let's do the same process as before. Humanoid apply animation, walking. And it should look Apply. Now let's go to D by controller and move the break dance and just drag the volcano mission. Now when we run it into a walking animation, right now it's looping and we will control the actual animation later when we added the idle animation. And to run animation. And we are going to control it by the variables in the script. Let's right now, we can move around by the keys. You can either use the WASD on the arrow keys or if you have a game, but you can use the joystick. And as you can see, the character controller provides us with a basic collider. So we can get through the car, we can go through the house or the books. There is a basic collision system already working. In the next part, we're going to add gravity to the player so he can fall. 5. Advanced animation states and gravity: We're going to add gravity and advanced animations that are actually going to represent the actual state of the character. So if it's idle, running, or walking, first, let's add a new object was seen. It's called the brief apps and the stairs are going stairs. Let's rotate it. So they are facing the player. And make it a little bit, little bit bigger. By scaling, it looks like the scale tool. And hold the middle. And it doesn't matter if it's clipping to the ground now, it goes. So you want to just, I just wanted to show you how the character controller behaves. At the moment. It's gonna go up and it's going to stay in the air because it has no gravity implemented. So we actually need to do implement our own gravity. It's a few lines of code. Let's switch to writer. And we're going to add new variables for the gravity. I've just commented here. It's going to be private float gravity. And let's use the actual number, which is 9.7. And let's add a vertical speed, which is going to control the falling speed. The horizontal or vertical move stays the same. But if the was add the logic for the gravity. So let's say if the character controller is grounded, just which means it, if it's touching the ground, Let's set the speed to 0. So if you touch the ground, we don't need to fall. But if it's not, we will be it will be we'll change the vertical speed to gravity multiplied by the time between the frames. And then we actually have to add a new vector for the gravity. And let's do a new vector tree. And let's add the the y-coordinate as vertical speed is at the coordinate also 0. So that's x-coordinate, y-coordinate, particle speed and Zed coordinate 0, 0. And now let's just add this to D controller move. And let's just edit. Do it. Go to move, timedelta, die. Okay. So now when we play the game, the character is actually going to fall because once he's on the top of the stairs, the gravity gets applied, then he fell down. Great. So I'll just go back straight again. The axial force. Great. So we just implemented gravity. Now let's implement Come on. Adaptation. For that. You're going to need a new object called camera at a holder and let's call it come in a holder, which is going to act as a parent to the camera. And it's going to have the position of the camera. So let's just copy position of the camera and applied to the newly created object. And let's say base position. And then let's drag the camera to recommend a holder. And now we're going to create a new script. Let's call it camera controller. Double-click it. And we're going to write our own camera controller. That's, that's going to allow us to rotate the camera. First, we need a transform that will hold the reference to the camera holder, because that's the transform we're going to rotate. Then we need some variables for the mouse and the upper and bottom limits. So let's, let's do public flow to Mao sensitivity. Let's set it to do. Then public float up limit. Let's do minus 50 and bottom limit. So now we're going to need to update method that we're going to fill in later. And end. Rotation method doesn't need to be public private. It goes, it's gonna get called Online from this script. Similarity as the horizontal movement. We need horizontal rotation so as to horizontal rotation and input, once again, if axes and this time mouse X. And the same thing. Control D to duplicate the line, vertical, rotation and mouse epsilon. We are going to rotate the player by rotation of the mouse, so on. So the next thing we're going to need here actually is to order a friend's 2 D layer layer transform. Let's say it where Transform Rotate. And the arguments are like the three floats. You're going to use floats. So let's go with 0 in the x-axis. And epsilon are some predation multiplied by most sensitivity and 0 here. And the same thing we're going to do with the camera holder. But here we are going to rotate the x-axis by negative vertical rotation with abide by most sensitivity, 0 and epsilon axis ends at xs. Then we need to save the current loop, current rotation. And let's do this camera holder. I'm going to save their local Euler angles. And if the current rotation x-axis is greater than one, I'm at 80, we are going to resident bank by 360 degrees. The next thing we're going to set the limits plus GO current rotation x. And we're going to use the clamp function, which is actually, as you can see, the description, it returns the given value if it's, if it didn't the minimum and max range. So that's exactly what do we need for delimit. Let's use the quantification x and a blunted and bottom limit. Like so. And the last thing we're going to do, you're going to change the rotation of the camera holder. Delocalization. And I'm going to say two quaternion LR. And you're going to give it the current rotation. And of course we're going to use the rotate function in the update function, we're going to call it every frame. Now. We have the script done. Now we just need to assign it to the camera. Hold down and use this dance form here and the platens form. Right? So let's test it out. I'm going to click it. I'm going to click the maximize on play. So the game maximizes. And actually, I can move around with the mouse and it changes the rotation of the player. So now we can walk around and actually look around. The speed is not matching the animation. I'm going to tweak that later. But right now, we can move around. And the walk animation moves kind of bad. So just add an idle animation. Let's download and the idle animation and just search idle. Let's find something that is suitable for our character. This looks fine. Download it. Our right. Let's call it breathing idle. Let's import it into our project. Again, the same deal. The animation is looping. And it's called vital. Something that blind or summary isn't good. Blight and the rec is humanoids apply. Good. Now it's called that a player controller. Drag it in and we want to use it. As I'm going to delete this, import it again. And I'm going to create a transition between these two. Right-click, make transition to here, and here, Make Transition, do here. We're going to be able to switch around in these animations. First, we need to add a variable that's called the parameters plus Bool, Boolean. Let's call it this walking. And let's add the variable to the conditions. The plus is walking. And when we're switching from idle to walking, the condition is true. And remember it was switching from walking to Idol. Whatever is false. And that's all we need to set up right now. In the animation controller. Let's go back to our script and do our player controller script. And let's add a new reference, public and they mate or an animator. And that's going to hold the reference to our animator obviously. And let's get to the move function and call an animator said boo, hiss walking. Because we named the parliamentary here is walking. So let's call it the walking. And we're going to add simple condition. If vertical moons is not 0, which means we are moving either vertically. Or this notation is orange. Horizontal moon is not 0. This is going to have a true or false value. So if VR, we have a non-zero value vertically or we have horizontal value non-zero. It's going to be true. So it's going to evaluate to this walking through while Alice is going to be false. Okay, so that's all we need here. Let's go back to Unity and let's assign the animator friends. Do the script and just take it. It is going to be more convenient if I just use this. And now when we run the game, he's going to stand around because that's the first. I'm going to just do it in this window so we can use the state machine here. To this, yes, and let's play the game. The first day is going to be idle. And once I press the forward button, it should change to, it doesn't. But the parameter is changing. Obviously. What it's done being sent to the controller. There's an error somewhere. Oh yeah, is there has exit time. Let's turn off their Has Exit Time. Now it's working. There was a dimer which was being used. So let's just so just thrown it off at that time. And now it's going to work immediately. As you can here. I press the button. It takes some small amount of time in the transition here. We can make it smaller. And it's going from idle to walking, which is great. Let's maximize it and let's see how it actually place. Good. Let's go into house. Now. It's still in the air. And we have we don't have any jump function. Wait, I'm just going to make the house positions go down a bit. Yes. Like this. And now we can go inside the house. So that's it for this part, the implemented gravity and basic state machine for the animations. And also they're looking around. In the next part, we're going to look at creating zombie enemies. Actually a horde of zombies, enemies that are going to follow the player around. And then the next part after that, we're going to implement delicate thesis, a special Power, BI. You can use boxes to defend yourself. You're going to attract barrios, objects with your mind powers and use it against the zombies. Anyway, that's it for today's part. See you in the next one. 6. Add zombie enemy spawner and code simple artificial inteligence: In this part, I will show you how to generate enemies underneath mesh. I will make them chase me and collide with the objects properly. First, we shall create a new enemy object. Let's do that. Just do great empathy and name it Enemy. Next, we will want to find suitable suitable object to follow us. You can either use the brief apps from the Oregon starter, but they look kind of kind of bad. Solid, just do something better looking. I found pretty great model on the Unity Asset Store that it's free. Just go to Window offered store search online that will take you to the Unity Asset Store. Search for zombie. And this is the one that's going to be one of the first results. It's a freeze on BIM model with animations. So just click add to my assets. It will add it to your assets. Now you can go to Window Package Manager and just search for zombie after the packages update, let's search for the zombie. Js. Download it and import it. I'll be the zombie here. Brief apps and just go based on B1 and assign it to the enemy object. And reset the position. So it's actually the enemy object. And reset the position here too. So it's standing on the 000, 000. All right. Let's move him a little bit. Dated him towards us. This zone B will be, the zombie, will be part of a heart. And the enemy AI and needs to know how to navigate on the ground. And so far we haven't enabled the navigation. So you have to do that first. Go to Window, AI, navigation. Click on Navigation static. First, choose the floor. The floor. We can, I guess you static new them, the navigation area, set the walkable, then go to bake and click Bake. As you can see, the floor changes overlay to blue. That's the novel mesh. But the NMI Model doesn't yet have the enemy object is an AED have the information how to navigate on it. We have to add so-called Nav mesh agent. Do it. So let's do that. Click on enemy, the inspector at Component and search for Nav mesh agent. It will create kind of a collider, same as the character controller. And this agent, this agent. You can change the experimenters here, of course. You can change the speed of the movement, acceleration and so on. But right now we want to change the radius and the and the dimensions so it matches the zombie. Like this. Radius. Gets a little wider. Yes, that should be should be fine. Okay, now we have the basic navigation ready. Let's go the logic. It will be a simple follow algorithm. So let's do that. Let's go to our scripts folder. Create a new script, call it enemy. Open it. Now let's add new private variables that will one we'll hold the nav mesh agent. And the second one, we'll hold the transform or the position of the player. Now, it will assign the mesh agent of this object by calling the method get component, which is a method for, as the name suggests, getting the components of this object that the script is associated with. So in our case, it will be the enemy. If it's not clear, it will become clear in about 30 seconds. Let's get the mesh agent. And also let's assign the target. And up there'll be the game object. Find. Blair. Or let me use the fine gameObject with DAC player. That's way more effective than the find method that don't ever use the find method. If you absolutely don't have to. It's not optimal to use it at integral of slow. Your performance. Always use the fine game object with tag. And then in the update method, Let's say that the Nav mesh agent and set the destination, which means which point it will follow to target position, so the player position. Okay, so that's the basic setup for the enemy to follow the player. Let's go back. Now let's change the player bag where object tag to Blair. Like this. And let's assign the NMR script to the enemy. And now when we run this, the zombie will start following the player around o. And the zombie has some default animations on. So it looks kind of funny because see, cycling through. For animations it seems let's change that. Does by default in the baggage. So Let's go to the zombie controller. Oops. And let's, let's keep only the working place. So let's delete this one and let's add on the walk in place with the hands stretched. Okay. Of your walks like a zombie. It looks awkward, but it works. And as you can see, you will be able to go through the car and go through the stairs and go through the house through everything. Because the nav mesh is not differentiated enough. If you click on the floor and go to the scene view, you can see that the objects are not differentiated from the, from the unity of the enough mesh in any way. So we have to tell the nav mesh that these objects are not walkable for the agents. So let's select the car, go to the object like navigation static. Again, as with the floor, change all the chat objects and make it not walkable. Again, yes, Ginger children. And then click on bake. Now, the car is differentiated from the mesh. And let's do the same with the bogs, the house and the stairs. So navigation, static, not walkable. Bake, bake. All right. Then the box not walkable. You don't have to bake it after each dime, but it will. I'm doing it so you can see at the changes and the house bake. All right. So right now, I can hide in the house basically or on the stairs. And the zombie will not be able to reach me. Let's see how that goes. Playing the game. I'm going to go on the stairs. The zombie doesn't know what to do because it has information only around the mesh and the stairs are not on the nav mesh. Okay, so I will now go into the house. And the zombie again has no chance to get here. All right, so that's it for the basic navigation. And now let's do the generator for the enemies. So it actually be a whole to zombies. Let's create a new object, call it Enemy Spawner, and create a new script. And MS spawn with camel case notation S. And let's prepare our zombie object. Let's make it a Prefab. Prefab is sort of our what's called the baggage that holds all the information about the object and all the associated scripts. And you can spawn it again instantiated as a new object. If that's confusing, don't worry, it's really quite simple. Let's create a new folder for these brief apps. And all you have to do is just drag the object that we want to make a prefab into the asset browser. And they'll automatically make a brief app out of it. We will now be able to copy it into the scene. And the newly copied object will always have all the characteristics of the previous objects. So that means it has the enemy script associated the nav mesh agent and so on and so on. We can actually now delete the enemy. And let's go to the script that we created. And I'm spawner. And here we will create a new variable called enemy. But we'll hold the graded prefab. Let's just call it enemy. In the start method as spawn one enemy somewhere in the scene. So let's go enemy. Spawned an Emmy. And let's use the function instantiate, which instantiates the objective, pass it. So in our case the enemy. And then we need the position. So let's just go with the tree 0, which is the absolute middle of the scene. And then put only an identity, which is a default for this. Now let's assign the enemy spawner script to them Enemy Spawner. And go to the brief apps and assign the enemy prefab to the variable we created. So it holds the reference. Now when we spawn, when we start the scene, it will spawn right next to us. I think here is the 00 000 and stuck to start choosing, jesting us immediately. Okay? So now we have to do the same thing. If you want to, 100's on base, we'll do that same thing 100 times, but on various positions of the nav mesh. So let's do that. Let's go back to Enemy Spawner. And this will be a little, little bit more complex. Let's first create a list for our enemies. So let's go grab that list of type enemy enemies. And then let's create a new variable for the range of the enemies. Let's call it number of enemies. And let's set it to 25 by default. And then we need, then we need a variable that will tell us how far from the, from the initial position the enemies will spawn. So let's go call it range and set it to 70 meters. And we can actually, let's use so-called modifier. And this case it's called range. And this will enable us to change the value of this variable. In the Unity editor just by using a slider. So if I save this, go back to Unity. There will be a slider default value 25. And I am able to change the value of the enemies. But right now it's not hooked to anything. So let's write the spawner itself. Let's create the new, let's instantiate the latest. And this. What's the problem? Oh yes. That's underscore enemies. And let's create a new force cycle. That's classic for notation. So if index is less than number of enemies, then increment the index. And just wanted to make more with this code here. So at grades, so it gets caught in the cycle. And we actually want to add the spot enemy to the list. So let's go and add spawned an Emmy. Now let's create a new method that will return a random position on DynaMesh. And let's call it random enough mesh location. That will have a perimeter of the radius we want to spawn the enemies in. And let's create a new variable for the a 100 direction. And we will use a method from the random package inside unit sphere. And modified by radius. Inset inside unit sphere, returns a random point inside a sphere with radius one. So we multiply it by the radius, so it gets its inner radius. Now we need to check if the random position, let's go to 100 position. Actually. If the random position is on our nav mesh, let's create a new variable for this nav mesh. Hit, hit, and pick a variable. Final position, set it to 0. So for now. And let's check if the position is on the nav mesh now. So let's go now. I've mesh, mesh, sample position. And the parameters are Source, Source position. So our random position. Then we need at the callback, the hit variable equated earlier that will hold the information about the intersection or the, or the resulting value of the check. And then the radius. And the last is we need an area mask, which is we will not be messing around with that. So I'll just do one. And this, we need to fix this. This is actually out variable and so it should be prepended without and the F. Let's do. If it's successful, then the final position to deposition of the hit. So where the random position from the inside unit sphere intersects with the mesh. And after this is done via turn, the final position. If this fails, it will be 0. So it will always been on the middle of the scene. But if we find the position, it will spawn into random location. So now let's change the position of the instantiate two random enough methyl cation. And do the range. Here is the radius. Okay, so let's save this. And now when we run this, it will spawn or much. Let's say, let's say I don't know, whatever, 50 enemies for the three enemies all around the nav mesh. So I will zoom out play and should spawn in the circle. So here is the NMI hoard and that is now chasing us as go and hide in the house so they can't reach us. Okay? So that's the basic algorithm for now. And we will slowly start adding some attack methods so we can defend ourselves some basic health, so the player can be damaged. And then we will make the game look nice because this is just a place holder. So we will use, we will add grass, we will add textures and better looking objects. And overall we will make a nice horror atmosphere. How do with this? So yeah, this is all for this part and see you in the next one. 7. Code TELEKINESIS as a special power: Let's implement or Kinesis. First thing we want to do is we will create our rigid body. Rigid body is a 3D object that is able to interact with the environment and uses physics. And each object that has a rigid body in unity becomes a part of the physics simulation. In our case, we want to use the QP as a weapon. So we will be able to use static analysis to drag it to us and then throw it onto D is on this, there's one problem though. We change it to the navigation static. So if we change the position of the cube, this hole in the novel mesh will still stay there. So let's just turn off the navigation static here and read bake. So the whole setup is okay. Next thing, let's rename the cube actually to Q. Or the box is better a box. Let's go to the Inspector. Add Component, rigid body. And then we want to add a new tag to this object. So we will be able to attract only the boxes. So for that reason, we are creating a new deck that's added egg box. Then go back to box and that actually assign it because it doesn't get assigned automatically. After creating a new deck, Let's duplicate the object a few times, as much closer. And let's duplicate it. Right-click, duplicate, right-click Duplicate. Let's replicate it. And a batch. Now when we run the game, these boxes will fall onto each other because they are all rigid bodies and are part of the physics simulation. Next, we will need, we will need a position to which the object we will get attracted to us. Click on the parent object and select Create, empty, nor either do a cube. So we can visualize it. This will be o here and make it smaller, like ten times smaller. Scale to 0.1. Enter game-like control or BioShock. The attractor object is somewhere near the hand. Because you know, the object gets us just find some BioShock dark. And he says, so the attractor object, or the whole position of the object is right. In front of the hand, we will do the same with the whole object here, and let's call it hold position. And it will be in front of the hand, like this. And it moves with us because it's parented. Let's get back to the whole position. Let's change it to its trigger. That means that the collider will not act as a 3D object in itself. It will not have any, let's say borders. So objects will not get stuck into it. It's like transparent object, let's say, or the objects can go through it. So that's crucial. So the boxes can actually get right to the object and not get stuck next to it will all become clear once we write it allocates a script. So let's create that like an ECS script. Let's go to Scripts. Create new C Sharp script. Let's call it the Aquinas's. Open it. We will want. For now, let's delete these methods because they are not dying the way we will recreate the miter if you need to. The first thing we will do is create a method called Reich asked, which will, as the name suggests, gas straight 0s from our hand to the object. And it will serve as a method to see what object we are clicking on in the game was great. Variable array. And let's called the viewpoint DRE method from the camera viewport point to Ray. And let me explain this. The camera main holds the main camera that we are using. And viewpoint viewport points to array. It Vale cast array in the position of the 2D screen that we are actually seeing. So the, in this case, the ray gets cast in the middle of the screen on this point. So Whatever he presses on, it will get cast from the point of the camera in the middle here to do object in the 3D game world. So let's create a new vector three and pass it. Coordinates of x, 0.5, which is the middle of the horizontal screen. And the same for the y coordinate, which is also in the middle. So it will get, so there'll be middle and middle. And the z. We don't care about that. Now let's create our re-cast. Hit variable. Will hold the information and about the hit. And now for the physics programming, which is a little scary at first, but it's really simple. It's called Physics break AS, which is a method for actually gusting the ray from the original point mass into ray from the camera, then the output goal back out hit. And we want to have some interaction distance. That's great variable for that. Or let's make it public so we can manipulate it in the editor. But bleak floats. Manipulation, distance. Let's initialize it to centimeters. And let's pass it to do manipulation distance. If this succeeds, if there is a hit on some object, we want to see if the object we hit was a box. So let's go hate, which holds the information about the object we hit. Let's access the collider of the object. And let's compare the bank to box. So we will see if the object we hit was indeed a box, then we want to see the health objects. So let's create a variable for it. Right? Sorry, brave at GameObject held object, object as the collider. Game object set at the health object Position. Do the whole position we created earlier. And we do that by calling the set bind of the dance form. And we want to set it to the whole position, but we don't have the reference to it yet. Let's make it whatever for it, public transform position. And put it here. I'll position, assign the balconies, This script to the player, and assign the whole position to the variable we created. Now, we need a minute to get the rigid body of the object we want to attract. In our case, the box. Because each of these boxes as a rigid body, which is the physical attributes of the object. And we will want to manipulate with the physics of the object. So we need the reference to its rigid body. Let's create a new variable for it. Rigid body walks, rigid body box, rigid body. Is the rigid body of the health object. Let's get component, rigid body of the object. Then we want to freeze all constraints. And then to freeze or which will freeze the rotation and motion. And on all axis. Then we want new variable that will hold the value. Simpler Boolean, true or false if we are holding an object or not. So let's go, let's call it holds with chick. Underscore holds object. And let's set it to true right after this happens. Okay, now we need some information about for simplicity, let's create a new boolean that we hold information if we are holding the object or not. So simple, true or false, private bool holds objects. And right after all this happens, let's set it to true. Like this. Now we need, now we need actually methods that too we'll move the object or opposition because of this. All of this does, is it gets the rigid body and it freezes the rotation and position of it. That's the first step. And that's the first step in the sequence that we need to attract the object to us. This will not do anything in this state. For, for that we need we need a moving object to position methods. Create a private void object to position. Then that's great. New method. Let's call it check distance. This will actually return a float with the distance to the whole top hold position. And it will use that here. It will move the object to the whole position for as long as the chick distance is greater than some value. So so easily understand it. Right now, the girl presses the button and the position is Miro hand. And the chick distance would return something like 20 meters. And the object will start to get attracted to the hand. And it will stop. Oh, she throws it right away. But it will stop. The moment it gets. It gets do the whole position. Okay, so that's what we want to do. In this method. So let's first make the distance method and then just returns a distance between the object position and hold position. That's all it does, which are distance in meters between those two objects. And in the MOOC objective position, we will be changing the object position continually. For that, we use the method letter, which is a linear interpolation between two points. So let's call it vector tree. And as I said, this loop method just interpolates between two points. So it does exactly this. It gradually, continuously changes the position from here to here. Smooth line like this. We start from the original position of the object and to be interpellate to the whole position. Sorry. And we do that by some speed. So let's create new enable holding the speed of the attraction, production speed. Let's set it to five. And we want to make it dependent on the frames per second. So we multiply it by delta time. Right now. We are able to attract the object. Let the chest hook it to the input. In the update method. Update. And the update method. We will check the left mouse button. So that's pretty easy. That's just the input. Get mouse button down. So that checks if a mouse button is down and we pass it the index of the button. So for the first or the left mouse button, it's 0. And if we are not holding the object, then we call the re-cast method. That's the first step in the sequence. So the re-cast gusts, the rain, checks if it hits the box. And then it starts the sequence. And most of all it sets the whole object to Drew. So next, we check if the whole object is true. And if it is, then we will start attracting the object. If the chiggers stance is greater than one meter, then we move the object to position. I've me change the notation here. It's a public so it should be should be check with. Should be like this. All right? Okay, so this is all we need for attracting the object for now. Could before this thing, this, I'm going to turn off the enemy spawner so the zombies are not bothering us. And I will make the interaction distance. But delicate nieces higher. And when I run this, it gets attracted. But do you have to align the middle of the screen with the box? Oh, yeah. So that's it. It's kind of hard to see where the middle of the screen is. Solid me add Canvas, which is in the UI. And you actually don't have to add Canvas, just add an image. And it adds an image right in the middle, right away. Just change the source image. Do nope. So it's circle like this and make it smaller like 55. And that's all you need to do to have a dot in the middle. Sexually, now when we press the mouse button, it gets attracted the object that's That's in the end, the end of the array we cast from the middle of the camera gets attracted smoothly. I have to denote the mouse also, so it doesn't come out of the scene. That's annoying. So let me just change that. I'm going to go to play controller. Create a vague method, which gets called right after the object is created, before the start method. And I'm going to lock the cursor. Of course, remote lot. And for services it Bowl set to false. Yeah. So it won't bother us. And in more. So it will not happen again. Click outside the game. So we can surely go here, click and gets executed properly. If we click again, nothing will happen because we don't have to logic program for that. And if we click on editing, that is not a box. It will not get attracted because it doesn't have the DAG box NOR and rigid body. So nothing will happen atomically going to box and gets attracted right through the whole position. All right, so now we do the drawing and releasing the object. So now let's do the, let's go to the delicate easiest script and add the methods for that. So release object then should object. So that's private void Rayleigh's object. And I'll admit that. Let's call it the shoot object. That's called the box rigid 4D and set the constraints back to none. Are they wear? So it gets, it can move freely. Then we need to unpaired and the object, because we bind it, parented it before. Do I hold position which we don't want anymore because we are releasing the object from our sort of position. And let's set the Boolean true, false. We're not holding the object anymore. It's holds objects. Also object force. And that's certainly how to object tool now. And for the shooting on the object, we need to draw force. So let's create a new variable. Public float, throw force. And let's set it to five. And we also need minimum and maximum values for this because we're going to be making the dough force dynamic. So when we present the right mouse button, it will begin sort of our charge of the, of the energy in the box. So the longer you hold the right-most button, the further away you will be able to throw the box. And for that we need minimum and maximum for the total force. So that's great. It meant roll. Let's go with dual and munched role. Let's go with something like then. Okay. Now the throw force will be right between these two values. And if the VaR holding the mouse button for too long, it can go above the mikes value, but we don't want that. So for that we use the clamp method that will always sort of stick the value right on the top of the maximum. So let's go through force vn set and then meant row. And monks draw. Now we have that row force and we won the rigid body to have this force on the man to be president should button. So it's accessed the rigid body, call add force. First, it needs a vector in which the force will move. And we wanted to move forward from the camera. So forward from us at this, from the main camera, camera main transform forward. And we want to multiply it by the force we just made. And the force mode is impulse. Because it gets, it gets, it gets thrown at once. So at four small impulse. And then we release the object, right? As we said, the force. We no longer have it because we have drawn it. So let's just map this to another key. Let's just do this. If you're not holding the object, we are starting the attraction. And if VR holding the object, then we shoot the object. Let's see how that works. Just play this. Now I go attract it and then I press it again, it gets drawn. But I said the default row for something like five. So it's very weak. Now, we actually need to make the functionality of sort of are charging up the draw. So that's pretty easy. That's actually a one line of code. And just go to the abatement that make a new condition. Input mouse button down, one, which is the right mouse button. And we are, if we are holding the object, then we will increment the row force. By 0.1. Oh yeah. Gizmos button, not the down, but generally if it's breast like this, because if it's down, it gets only called once. Let's do it again. Now it gets incremented in S2 insane values. But they did SCAP clamped at the 2020 meters or 20 TO force. Now if I release the button and press the left mouse button, and it gets drawn with a greater force. But it's still not great enough for my taste. Let's make it to 101. There is a possibility it will go insane the physics system and click-through other objects. Well, let's try it anyway. Hold the right mouse button. It's 40 now. Oh yeah. So that's quite some force. Let's get to 100 or even over it because we have clamped it. Oh yeah. Nice. Okay, so the shooting works. Now let's add some fancy little Thanks. Let's make the, make the box rotate when you attract it and hold it. That's also pretty easy method. Let's call it rotate box. Let's access the health object transform and rotate. And we want some vector that will rotate it in. We don't have that yet. So let's create a new method, Robert Boyd, calculate vector. Here we want three values for x, y, z squared, then new variable for x. And we want it to be random. Let's call random indention random range. And let's make it random from minus one to plus one. Saying the same thing for y coordinate and z coordinate. Now we create a new vector, data vector and assign the values to it. So as XYZ. And this gets called. Once we make the re-cast, we don't want to like calculate director each time. With each frame. We want to do it once. V, attract the objects or let's make it a sweet here. Okay? And now we can use the rotation vector here in the rotated box. And now all we have to do is the goal of data box. If behold the object into our rotate. Once I attracted, it all started nation. And so I already said the rotation stops. Okay, that's where the rotation. But what if we don't want to show the object? What if we want to release it? And we make up our mind, we don't want to attack the enemies. That's also easy. Just add another input. Let's map it to let's say df. Let's access that by t coat. And let's go, go to F. And we have to hold the object. So you can really sit, just called the release object. And it will drop the object in place, f. F. Alright. Now we can hide the odd position so we don't need to see it anymore. Let's just do they're not the measure in there and leave everything else intact. The next thing we can do is add a Rigid Bodies to other objects in the scene. So the book says, The drawn boxes will interact with it. Let's go to the car. Add a Rigid Body. Let's make it heavier, say three. And now when I draw the box into the car, it will move the car a bit because it's heavier than the box that most on their bit. Well, it's still on heavy enough to guard to 15. And the box shouldn't move it. Very much. Now. It's heavy heavy car. Oh, yeah. You have to hold the right-most button for real along before you can have any force to move the car. Okay, so that's it for this tutorial to have fun playing with the Kinesis? In the next part, we will be implementing a damages them to the player. And the brakes will be, the boxes will be able to damage the enemies and Gilda zombies. That's it for today. I'll see you on the next one. 8. Zombie attacks, player health system, death animations and UI: In this lesson, we will make the zombies attack the player. The player attacked zombies. And we will add various tweaks like budget of particle effects and animations and so on. Let's start with creating a new particle effect, which is, which will serve as sort of a burst effect for the zombies when they die, they will burst into a bloody mush source, create a new particle effect. Let's go to Effect particle system as well, spawn and default particle system. Now, we want, we want it to resemble our blood effect. So you all make it red, move it in front of the player. So you see the effect also on the, in the game screen. And we will tweak the parameters of the particles so they resemble blood. Let's change the duration to one. The lifetime will be, then the speed will be a bit bigger and make it to 30. But the start speed, we want it to be a burst speed, so let's make it higher, like 30. The start size will be very small because there'll be sort of blood splatter effect, the rotation. You can leave it to whatever. But I was lived to 90. Just experiment with the parameters. The gravity modifier. Let's make it 29. So it will use the normal gravity constant is 9.87. And then we want to change the shape of the emission rate over time. We will make it a 100. So there is a lot of particles. The shape. Let's make it a sphere. So it bursts in all directions. Size over lifetime. Make it go down and change the curve. Let's make it a go smaller with time. And then we want collision. So it collides with the world and just change it to world. And we'll start colliding with the objects in the world. Also change the parameters of the dampen the one and bounds to 0. So it doesn't bounce. I'm going to make it the articles for now and dampen. Let's make good 1.10.8. So it isn't a sticky. Okay? The only thing we need to do now is to change the color red. So it doesn't go splat. It's kind of glitchy now because it's really stop the simulation, change the color to red, and then run it again. It's nothing special. What do we do the job? Okay. You don't want it to loop. Just play it once. Now when it goes on and once it looks kinda thick, Let's do 12. And we want more particles, such as US. And right or down to 500. And let's make it a bit bigger. It's too much. Okay, so that's it for this. Until serve as the blood splatter effect. You can play with the parameters as the lake to make it more realistic or a dexterous or lights or whatever you want. Let's make a prefab. I will have their particle system, Let's call it flooded, split up and drag it into day as a grocer and delete it from the scene. Now, we want to collide with the enemies. We want the box this to be able to collide with the enemies. And once they do, we want the enemies to burst into these particles. Let's go to the enemy script. You'll be add a new method called On Trigger Enter, which is a method that checks if the objects collides with another. Right just on Trigger Enter and read through and compare the dismantle. It gets called each time the object collides with anything. So let's compare if the order collided object is, has the object DAG box. And let's also check if the box is moving. If it's drawn, it has to have some speed too. Damage the player, I mean the enemy. So let's just use a math function. And if the author attached rigid body of the object of the box has a velocity. Unfortunately, we have to do it by the various coordinates x, y, z individually. So let's check the y. Let's check the x-coordinate. Or the y is higher than five, for the z is greater than five. Okay? And once this happens, we want to instantiate a debt splash or blood spots by the effect as we graded, graded it here. So let's, let's play that buys all of them are able at splash. That's a public gameObject that splash. Although the holder of France to the d plus B2 effect. Then we want to spawn it on this position, on our position on the enemy. And again, default button in identity. So we spawned a brief EBITDA, buddy glow effect. And then the V, the destroy ourselves. Okay, and let's go to the enemy prefab. Prefab and assign the blood spot to here. Add collider. Looks glider. Make sure now let's make it a capsule collider. Change the boundaries so they match the enemy of good enough and make it a trigger. So now when we play the game and draw a box, the zombie, it actually works. And splashes the zombie into bits. It's really quite satisfying. And the blood spatter stay on the ground and die and they get smaller. Almost don't notice. Notice that being away. Let's make the Enemy Spawner a spawn more enemies. And let's have some fun of it wasn't. And a force as hold the right-most button. Okay. So now we have a basic weapon against is on this. Okay, now make the, we will make the enemies attack the player and dimension. And he was there at the animation against the player. So for that, we will need the zombie. Do have the animation. Let's open the prefab zombie zombie controller. Open that. Let's put the attack animation in. And let's make a transition between those animations. Transition back, right-click on it and make a transition. And then we need parliamentary, same as we did with the walking animation in the player. Switching between the IDL and the walking. So you make it a bool, call it a back, and add a condition here. So when we are going from walking to attacking, that, that must be true. And if we're going to be our position from attack to walking, that deck must be false. Now let's go back to the enemy script grade variable that holds the animator. Let's assign it as a cash or unable and start method. And now we need a new method that the veil detect if the enemy is colliding with the player. And for that, we don't need a bigger collider for the player. Let's set new Collider. Or rather, yes, make it, let's make it the player object. Let's add component, books, glider. And this will be solely for the zombies to detect if they are close to the player. So let's make it two meters wide. And once the zombie collides, cells colliding with this, let's make it a trigger so it doesn't get in the way when you are walking around. It's like a transparent object. The zombie will know it's close. It's in the proximity of the player. So it will know that it can attack and run the attack animation. All right, so let's go back to the enemy. And greater method On Trigger Stay. And if the other object that we are colliding with has deck player, we will, we will attack way the other animation. And that's not the only thing we need to do here. We actually need to time the animation somehow because if I just set the animation here to play, it would get caught each frame, the condition is true. So that means this method will get called 60 times a second if we would have 60 times 60 frames per second. So the animation would be constantly in its beginning phase for that and for that reason, we need something called a coroutine, which is a tread of the program that we can make timed, we can provide a timer. You'll be so if I just show you for this unit, you need eye enumerator, which is a specifier for the for the method to be a coroutine. Let's call it I enumerate to attack. And here we need to return the new weight four seconds. This is the method that's used in coroutines, in The basic ones anyway, that returns the control to reprogram. Or rather it returns from the threat. The program itself can run in the main cycle anyway. And here we will change the variable for can attack. Let's call it private. Private boolean. Can attack, attack, and default is true. The first attack you can do, zombie can attack the player. And this coroutine sets the can attack the true also. But once we collide with the player and stay in the glider, then we check if can attack. Then here we call the deck animation and the attack method. Then we set the attack immediately to false. So the next frame we are colliding with the player. The zombie will not attack anymore. But we start a coroutine that will set the flag to true again after 1 second of waiting. So. Attack. And here we actually call the method for blamed animation and sorts all sorts of things, all sorts of other things. So it's great that Mao private void at that layer. And we will call that right here attack player. In this, we access the animator and set Bool attack, which is the one we created in the, in here. As a parameter attack. We will set it. Do. We set it to false after the attack is done? And actually let's move the whole logic. This is scattered. Let's move the whole logic here like this. Okay? Let's test it out. This should work. Once the zombie collides. There's no animator attached to the enemy colonial game object. That's a problem. Let's go to our prefabs and ME. Open brief fat. There is no animator. It's in the child object. So we actually need to get component in children. And the arrow should go away. Yes, the zombies are attacking, but they are taking only once and then they are stuck in the state. They don't have that anymore. Let's try it with one Zombie so we are able to see if it works properly. For a few zombies. Okay, on the one zombie to the x, there is some delay because of the AI machine controller. And change the transition dimer. Two absolute minimum. The number has exit time and also has a dime turn off and make it do absolute minimum. All right? At that index right away as it starts gliding. Yes. And periodically attacks once per second. It plays the animation about liking once per second. Now, we will add some sort of object that will collide with the player and damaging. So let's add gliders to the mouth and the hands. Good, Let's go to the enemy prefab. And we will add the new object to the amount and the hands. So let's choose the hand, arm, palm and create a 3D object cube. Make it smaller, like this, and move it to the hand. The origin of the object of the poem is somewhere else it seems so. This doesn't get associated right into the right position. But no matter, Let's create a new tag. Let's call it damage or Altaic dimension. And let's assign it to the mature object. And then also two-dimension. Now the duplicate this, and we will add this also to the right. And like this, and one to the mouth. So supplicate it again. Or do they head? Like this? Hey, let's keep these objects visible for now. And I'll solids. And you get a trigger object. The glider. Make a trigger. Now let's go to the scripts folder and create a new script. Let's call it mortality. We will edit as a new component to look to our player. And it will have a simple logic. It will have private. In HB, it will hold our health. And let's make it visible. And the editor, even though it's private, by making the glass realizable. And let's add an attribute. So I lives field to the HB. So this way it will be visible in the editor even though it's private. And it would normally not be visible. For debugging reasons, let's keep it in like this. And let's make a new method called private, private dy by dt dy. And this will be empty for now. We'll just make a Debug lock. You died and a public method, public void, date, damage, and perimeter, HB or dementia. And now, if h b is greater than the damage, we will subtract the damage from the HB. And if it's less than that, we die. And I will add on the book club here, taking damage. This. And also we need on Trigger Enter. And we will check if the colliding object has a tag, the imager as you created for the enemy earlier. So if we are, if you are colliding with the D-major, we call the damage and say then HB. And we don't need these methods. Now all we have to do is add mortality as a component to the player. But let's not add it to the player object because the object already has a quite big collider and we want them to be smaller. So let's add component, capsule collider. Let's edit it so it suits the player. Like this. It looks, it looks good. And let's add the mortality component to here. And the enemy should now damage the bilayer of it, these objects. Let's test it out. Oh, it doesn't. That's bad. And what's worse is that the objects are not properly oriented to the hands. Okay? The issue will be that we didn't add a rigid body to these objects. They need a rigid body. And we don't have the gravity for these. And now when we run it, it should collide properly. Yes, it's quite improperly, but the major objects stay statically on the place of the of the D, both of the hands. So we need to fix that. Yes, we need to use the skeleton of the object. Human spine. You're going to engage left arm, upper arm, for arm, arm, palm. Ok, I need to assign the the major two here. And the same thing with the right hand and with the hat to the jaw. Okay, let's save this. And when we run this, there's zombie will damage the bladder properly. They did it, it's hands. Right? We have that. Beautiful. Okay. The zombies now are able to damages. So it's turn off the mesh renders for the imagery of objects. So it looks better. This once more. And once we get enough damage, we die. Let's implement that to adjust the Donald an animation for dying. Let's go to maximum depth. Let's find some nice animation for dying. Just looks decent. And some of this dark mode. Meanwhile, I will add a new variable or rather a new method. And let's make it public. Bool alive. And the burdens, if the HV is bigger than 0, greater than 0. If V are alive, then we die. Because the dye function would be called each time the HB is not enough. So as happens when we tested it, write down the function, go get, got called multiple times. Okay, the animation is done on it. Let's go back to the Animations folder. Drag it in. Okay. Player controller. That. And the death animation rake, humanoid, apply animation. Let's call it die. Let's look bit and apply it. And and then we add the death animation to the controller like this and make a transition from idol and from walking. And we need a new parameter. Let's call it die. And set the transition to die when Drew and time also and die through legal actually. Move to the die animation. And I forgot it will not be looping. Bly. Ok, and now we change it in the goat die. Right? Okay, Let's test this out. Now, the animation should play. We should die successfully. Yes, we died. But the animation seems to be stuck in the middle. The problem with an emission parameters. Take the bake into both in the y-coordinate and Bly. Let's play again. And it will work the unmentionable place to play correctly and the player will fall to the ground. But after we die, we can still move around because the blade controller doesn't get detached. So after that, we want the player controller to detach from the player. Sluts. We can either make it in the code via some condition that if the mortality alive is false, we will not be able to move the character controller. But perhaps the more fast forward method is that we find the flow controller and turn it off. So let's go to the diamonds. And let's find game object of type player controller and gets component controller and enabled to false. Now a new blade or a stimulant not make it maximized. So we see that the blade or controller will be ticked off when we die. Where are the zombies? Kill me, please. Yes. And now we can look around, but to be can't go looking around. It's also a problem that's in the camera controller. And the camera controller is in the camera holder. So you want to make the, you have to be able to do the same thing with the camera controller. Just copy the line. Camera controller and it's in the camera controller. I don't need to do to get the component here actually because it gets the component straight away. Okay? So let's see how this behaves. Right? I can't move the mouse or move around. Great. So we have actually died. And one last thing, Let's make just a place holder text on the screen that will show us that we died. So let's add a new text object into the Canvas. Let's go UI text. If you take smash bro and go with that. If not to go with the classic text, that the by blend of editing the text is the same more or less. And let's change this to die text. And I can say You died. And also, let's add a new, new image that will be transparent and be transparent slightly. And it will stretch in the middle. And let's make the text go above it. Let's make it red. And let's make it out to size. So it adapts to the size and also change the kind of S two to scale. With screen size. Let's go back to the dye text. And it will make a new object create empty dye overlay. But both of these into it, and then turn it off. And all we need to do now is to show the dye overlay when we die. And from that before that we need the reference to it and the mortality. So let's go public. Gameobject, die overlay. Let's assign it, sign it here. And now just go die overlay. Set active, true. And then we spawn. We want to hide it if it's not hidden already. So just use a vague method that gets called right up to the object, gets spawned. A terribly seductive false. And now when we die, the overlay shows up it out. And that's the last thing we will be doing here. The next part, we'll make the game actually a look beautiful. 9. Enable CLOTH SIMULATION for the player's cape, use better models for the player: In this lesson we're going to replace it displays order model for something real. So let's go do the Unity Store and search for man. There's actually a free model called man in a suit. Don't know that. Click add to my assets. And now when you go to Window Package Manager and search for man, you can download it and then import it. So let's do that. After importing the model, go to a new suit bank suited man, brief apps. And there's the model, drag it into the scene. And it already has a animator attached. So just change the controller to player controller and replace our model with the blue suited man. It's going to be a bit tricky because we will have to replace the model completely. Okay, So there is a capsule collider and mortality script. So let's just copy this component. Click these three dots. Copy Component. Go to Command. Click on the three dots and go based component is new. Now let's rename this to land. And now so that we have to change the tax. So Inspire is mortal. Change demand to mortal. There's also the capsule collider. So copy that to component, go to man. Paste Component as New. Now we can disable the player and put demand on, onto his place. And let's reset it's his position. Like this. One other thing we have to do is we have to assign the animator to the player script. So go to d by an object. And then do the player controller. Click on the animator and choose man instead of blair. It will assign the new animator that's on this new model. And also turn off the Apply root motion. Okay, now when we save, our new model, should be walking like the previous one. Okay? Yes, walking around. Now we will add a running animation. So the game, because currently we can't run. So when we spawn more zombies will be pretty much screwed. Okay, so let's implement running. So it'll be very easy. Go to the code controller, create a new public float, run speed and set it to, let's say, cloth. And for, for coexistence, let's edit this six to six F. Now let's create one more variable. Current speed. And the current speed, there'll be dependent on us pressing the Shift key. So let's just go current speed equals. And now is the time for something called ternary operator, which is basically an if condition written on one line. Let's go input, get key. And we're going to, we're going to use the Shift key for running. So let's just detect the Shift key. And shift. This course will detect if the key is being held. And if that's the case. So question mark, if that's the case, use the running speed. And if not, use normal speed. This is the notation of a ternary operator, the semicolon and the question mark. If this condition applies, use the first, if not the second. Ok, and let's change the current speed here, like this. And now when we run the game, we can walk around on my end. When we press Shift. Let's walk around and it will shift the move faster. Let's hook this also to the animation controller. So you need actually an animation for running. So you're not floating around like this. She was horrible. Let's go to maximal. And let's download a run animation running something like normal. And it looks for a normal click in place. Download, download. And let's put this into our project animations. Let's drag this in. Let's change the parameters of the animation. As we always do an animation. Let's rename it to run. And let's loop it. Okay, click Apply. Now glue the player controller. And let's add it here. And then you transition from walking to running. And from running to walking. Create a new variable, nu boolean variable. So true or false, call it R1. And then click on one of the transitions. From walking to run. Make the transition shorter. The movement will not be as smooth, but it will be immediate. Turn off their Has Exit Time. Create a new condition. Like run through and where we are going from running to walking. Do the same thing and go run force. Okay? So now we will go down here. Go onto my torque syllable. Run. And this will be true if the current speed equals to run speed. Let's try it out without maximizing. So you can see the animation state. Let's go to player object. Actually, man, here's the animator. Click Play. Let's try it out. So now we are walking and now we are running. Oh, it's feet look a little weird, but that's the issue of the animation we picked. It looks kind of funny, so let's keep it in. As you can see, once I stop holding the Shift key, it immediately snaps. It looks unnatural, but it will do fine for this small project. You can tweak the parameters of the transitions if we wanted to make better. But for now it's sufficient. Another nice thing we can add is Cape, that the player can have to see what I have in mind is actually kept from Assassin's Creed. It's something like this. So a nice little cape that quivers in the air and the wind makes the manufacturer look pretty cool. And even the new games like little appeal to one, have this. So let's just implement this. Let's give our character, okay. It's pretty easy. We just need at Cape to the model. And then we are going to turn on the cloth simulation physics. Let's find K8 model. You can find one on, which is an alternative to the Moodle site. Very cunning get free models. Just go to sketch up like this search for KP. And it's going to be the second result. If you want to use these models in your game, make sure to credit the original authors under the Creative Commons attribution license. Okay? So this is a K8 model, or you have to do is download it. I've already downloaded it. It's as it file that you extract. And it contains data, the model in a blended format. Let's go back to our project and create a new folder, name it models, and drag the cape into it. Okay, Let's now plug it into our scene. And it's a little bake. It has a few issues. It's oil bake and it's transparent, which is the main issue. We can scale it down easily, but the transparency will be an issue. For that is an easy fix. There is something called double-sided shaders package that you can get under Unity Asset Store. That will fix this solid go-to unit Asset Store and search for double sided shaders. And here is the free package, free double-sided shaders and add to your assets. And then go Window Package Manager in my assets and search for double, for example, and download it and import it. Right now we need to apply this shader to the material of the Cape. So if you click on the cape, you can see that the model has the real court no name. When you click it, you'll find it right here. And you see that inside the 3D model, we need to get it out before we can edit it, because now it's grayed out. You do that by duplicating the material outside the model. Just select it and press Control D that will duplicate the material and create a new copy outside the DEA model. Let's rename it by pressing F2. And let's name it. Okay. Material. Now, here's the shader that he can change. Click on it. And double-sided sheet lists are in the second RStudio. So go synchronous Studio, see a standard built-in light, standard and opaque. And here's what a switch double-sided. Just turn that on. And it won't work yet because we must apply the material, material to the Cape. So take the material and drag it on to the cape and it's fixed. Okay. Now we have a cape that's opaque and we can use it on our character. Let's first scale it down. So it's going to be better if you use the scale tool instead of using the numerical values this time and move it to the player. Okay, the cape seems to be so, so and even fits the players shoulders. But let's make it a little bit smaller. Okay? And now we just have to add a clot component to the model of it, the skin measuring there. So go to the Cape, click Add Component and search for growth. And now when you run this, it's going to fall right through the player into the ground. And it's not going to collide with the rod at all. Let's see. It's going to fall infinitely. I'm going to turn off the zombies for now. And that's because it has no colliders associated and it has no strong points. So we have to edit that. If you want the cloth to interact with the character model, we need to add some collision, some gliders. We do that by assigning capture gliders, which are here, down here, capture gliders. Let's add three. Ones are going to be for the torso and two for the arms. Let's add a new module to the player modal. Click on our man, right-click three Object, Capsule, grade by default, capsule that we are going to edit to fit the torso of our character model. Go to the orthographic view by clicking this cube here. And let's manipulate with this capsule. Okay, After modelling the capsule properly, changed the capsule collider to trigger so it doesn't interfere with the physical objects in the scene and may never the main model. And then go back to Cape and assign the collider to the first spot in the capture gliders. Now the clot should not fall through it. But let's see. It does it does fall straight through it. That's weird. Let's make the radius a bit bigger so it actually fits the model. Okay? Now it gets stuck, as we've seen, as you saw, the cable gets stuck for a bit on the collider. And that's what we want. All right, so that's the first step. And now we actually need to hold the cape in place around the character snack. So let's face it there. Turn off the mesh renderer here, and make it a bit more fitting the collider. So change the parameters of the collider. Okay. All right, That fits the torrid zone better than before. And now, go back to normal view. Click the cape, the cape under it, and go to the cloth component. And click this button here, edited constraints. And and then go to the Select card. And here just select the points that you want to hold it in place. So let's say these points around the neck, many hold Shift, you can select more points. Sought the development hold roughly this area around the neck. You can be more precise about selecting the points about this is sufficient for now. And then click on the max distance. Okay? And when it's max distance. And now will be played in simulation, it will hold the points in place. Okay, now we only have to move the cape to their mind. And it's a little walk around with him. We're going to fix the clipping in a moment. But it's imperfect. It's very imperfect. But it's something, most of all we have to edit the dorsal collider so it doesn't clip through it. Okay, So the issue is that the cape is too light. Let's go back to the cloth and let's play around with the parameters. So let's make the dumping bit higher. Let's make it 0.5. Let's make it a friction one. And make this stiffness higher. Let's try it now. Okay. Let's spine to do the glider dorsal. So it's actually parented to the body. At least seemingly to the body or the head. That seems more fitting. Let's go to Group main information system, root, spine, spine, spine, chest, neck, and that's assigned a gate to the neck. The neck bone. Let's make it fit more. Okay, That actually looks decent. It's usable, It's not perfect. The gliders need to be more precise, but it reverse around in the air. And we can actually change the random acceleration of the cloth and random positions. So it delivers a bit randomly when you stand to simulate wind. Okay. Let's make it a glider of demand. Or actually the capsule collider. It's where is it? Where the torso. Let's make it a bit thicker. So the cave doesn't clip through the back of the character. So much. Okay, So the bag seems to be okay. But now we need to do the hands so it doesn't slip through the hands. So let's make new mic, new capture gliders for the arms. Go man to the object capsule. And now we need to fit it to fill the arm space. Let's make it smaller. You can move around like this with the middle mouse button. Okay? Okay, this will be enough. Now let's make it a trigger. Name it glider arm, and aggregate it. And let's move it to be an under arm to the other arm. Rotate it so it fits. All right. And now assign the gliders to the cape. Again. Go to Cape cloth and drag the two gliders. Two slots we created. Okay, save it. And now the hands, the arms should not be clipping to decay. But anymore. More detail, we have to actually assign the equators to the 2 D. And let's call left the arms. Shoulder, left shoulder. So this one and the right shoulder. Again. All right. This seems to be working nicely. Let's make the camera a bit more third-person with more far from the player. And rotate it. And, and let's change the field of view of the camera. Oh, and let's turn off the renderers of the gliders. Social glider, arm. Select both of them and don't have the mesh render. So disappears. Okay, Let's just start with the cloth simulation now. All right, it looks good. Okay. In the next lesson we're going to make the scene look realistic and add real models and terrain, objects, trees, grass, and so on. 10. Atmosphere: Model the terrain, paint trees and grass: Now's the time to completely change the scene. We are going to remove all of these placeholder models and use actual models that would work in a real game. And we're also going to paint a terrain. So we're going to replace this plane down here. And we're going to create a new terrain. So just delete this and go to GameObject 3D object terrain. This is going to create a new terrain. Just move it. So it is under our 3D models. And now we are going to need ground texture to paint it with. V also need to don't know that first. And I compose this a list of packages we're going to be using. All these packages are free. You can get them on Unity Asset Store. So let's go with the outdoor ground. It's just first, go to a store and download this package, how doggone textures. And as we did before and just add to my assets. Then go to Window Package Manager. My assets here, search for the package downloaded in my case update, okay, import it. Okay, Then go to terrain. Click on paint terrain. The second icon. Then you need to do paint texture. And here, edit the rain layers, Create Layer, and select Ground, fine ground. It's going to find a lot of textures from the PACU import it. So let's use anything that looks like a dirt sought, this one. And it gets painted automatically. You can mess around with the normal map that's also included, I think. Oh yes, there's a diffuse map, hazmat, metallic and normal map. And to give somebody the parameters to make it look different are smooth. And again, a change, of course, the dynamics of things. So it's going to fit more. What do you imagine the dirt to be in your scene? Now, we need some houses and trees and grass. For that. There is the grass and flowers back. Let's turn out that. Also add to my assets. Then go to Package Manager, search for the package, and import it. All right, Now we're ready to paint our grass. Select the terrain. Go to buy in details. It's the fourth icon. Create New Brush. Select the grasses that you like. Grant go with normal looking grass like this as T2. Then you need to do Edit Details, analogous texture. And here select the same texture. And you can mess around when the bit width and other parameters, you can dynamically edit that later. So we're going to see how these parameters affect painted details in just a moment. But let's, for now, let's leave it for the default values. And click Add. And I'm going to make the brush size smaller. And when you click left mouse, you can paint the grass just like that. And when we click Play, it already has some wind parameter turned on so it quivers in the wind. Okay. We can, we can paint the whole scene like this. So let's do just that. Go to terrain details like the grass. The grass is disappearing many flyaway. Just change the visibility parameters in the settings and make the detailed distance 150, which seems to be the maximum. Okay, Let's Spain some more. Just let's paint around the house. Goes. I going to be trees. So there is no need to unnecessarily maybe the grass everywhere because after all, it takes some performance to render all of these grass. Ok, and let's add some new grass texture, some red spent at that. And that's the 8th of the, of the brush. So click on the details and it, and can mess around with the minimal height. And Bandwidth is, and now when we play, we have more details in the game. All right, this looks hideous. So let's delete it. You can do that by selecting the grass that you want to delete and holding Control and just erasing it. This is not the only thing you can do with terrain, of course, you can also paint mountains. Go to the paint, rain. Here, select race or Robert terrain. Select the brush like this. Make the size bigger. So just in the far horizon. Let's create some mountains. So you will not be able to escape the zombies. And change the brush to this scattered one. So you can actually paint some details and make the opacity a little bit harder. So the details are like this, but the ok. Now let's add some details to the blocks. The dirt. Just change the brush size, something reasonable and the opacity. So it's at least resembling real mountains. All right, let's see how that looks. Okay. There sounded massive mountains. So that's it. Now let's add some trees. For that. We're going to need the dream forestry Store. Search for that. Click add to my assets. Now again, Window Package Manager. We're sure that imported. Okay, and the same way we imported the we use the grass, we're going to use the trees. So click the paint trees. I can click edit trees at three. Select the game object. And from the bag we just important to have a red would select any color you want. Click Add. Select your brush size. And you can start drawing. The red binds are massive trees in reality. So this scale is okay. Let's make it more dense. And also the hate spread. Let's make it like so. Okay, let's see how it looks. Now there is an error actually. Free Cam. What is this? I don't need no scripts. Reinforce three. Script, free cam, delete this. Okay. Oh, this looks horrible. This looks actually horrible. Let's make the trees way smaller. And there seems to be you a bill boarding effect going on. The boiling is when the textures face the player and nukes around. So this is just bad. Let's delete the trees. Make the brush size very large. This control, select the tree and the big old trees. And let's make the three smaller. Way smaller. And vein them again. Okay. Seems more rational. I don't need this. Ignore it. Okay. This looks better. But the trees, I still have some kind of a billboard effect. Let's see if we can fix that. In the settings. Should be in the settings. The boarding start, let's make it after 1000 meters. Okay, that worked. Let's change the models. And for that, there are few packages. If you want to go with the city environment, go with the polygon zombie back that contains a supermarket. But we are making this forest so some cabins will be more suitable. Let's search for polygons defect. And it's this one. It's actually a massive, massive asset that contains a lot of models. So click add to my assets, like each manager, search for the package, download it and import it. Okay, now let's go to bind and circles. And in the pre-fabs folder, there is various debris those assets you can use. So let's first use some buildings, some sheds, and place them around the place. Seems to be two times bigger than normal. Now let's add some shop sheets. Walls. Oh, big asset doesn't really fit in the forest. This seems to be like something that could be in the forests. Let's read the house. They did. Sides seemed to be okay. Well, actually it doesn't make it R. So on the half size, it takes you right to the objective you are looking around, plus f, it takes you right to the objects here we're working with. Okay, let's put some light inside an air. Does this baggage of any fire or okay. There is light. Let's put that in turn over the sea lighting so we can actually see we are creating. All right, Let's run through all and let's put a light. Do it. That's it. Let's turn the light back on the scene. And let's put some boxes in here. I didn't include one was great that our bottles smaller. Snubbed him to the ground, DAG them books and add a rigid body. So duplicate this bottle. So we're going to have some fun. And also Stone's great. So let's play some stones around. Select them all At bag books. That component rigid body. Right? Now it's just this out before we start adding more stuff. Oh yes, there's a problem with the glidant, the objects. So just turn on the convex glider. So it is continuous all over the object. Convex like this. Okay? And now we can use like an ECS on these objects because they are tagged as a box. All right, great. So move delight. You can keep these boxes. Let's just change the texture. Has changed to something would have a wooden texture. You don't so I'll just change it to anything. It was embassy would bark. Okay. Okay. That'll be they'll do fine. The darker bark. Looks good. Okay. Let's move these placeholder objects. All right. And I'm going to add another prob. I saw our street lamp in there. That shouldn't be a street lamp in the forest, but does matter. Just so you can see, where are we going? I light the lamp. Let's make it more intense. And turn off. The directional light. Might get minimal. And of course, the Skybox needs to be changed due. We want a starry night and such day unit as it store again. For a star field Skybox. It's a free Skybox that looks at big at their assets. Alright, now go to Window, rendering, lighting. This will show a Lighting window, put an environment, and change the Skybox material to the Skybox. We import it. All right. Let's see how it looks with it. Looks spread the big, but you can still see through the trees that's, doesn't look so big. So let's either make more trees or make mountains. All right, Let's make mountains. Paint the rain. This o bit too much. See how it looks now. Okay, The atmosphere is still not so great. And there are no zombies and no music. We will edit later the music and sound effects. Now. I'm going to add another probe, actually a land surrounded lighting system a bit. Let's add light and shadow. And how does this look? Let's use this lamp. Light inside it. Do large and negative books. Like it's convex and other components, rigid body. Always kind of vague. Let's make it smaller and change the color of the light to yellow. Light intensity 5. And make the shadows shadow, hard shadows for better performance. Okay, we have to turn on the shadows also for the other lights in the scene. Shadow type. Our shadows. Let's go for soft. Yeah, it's more atmospheric. If you have a border for BC, It's going to be not shoot for you. But other than that, choose harsher lose. All right. Let's change the light of this, the intensity. Do eight, it's a street lamp. After all. That's better. Okay. Let's let inside the house also use more intensity as implicate the street lamp. So you're going to have more light when we move around the scene to be spawned a zombies. And let's turn on the Enemy Spawner. Back on. And let's see how that looks. Zoom be smooth, way too fast. All right, let's make them slower. So I'm busy, I'm busy and be prefabs, enemy prefab. And speed 1.2. Let's make the eyes of the zombies goal more. Just called it a prefab. Go to the like the ice texture. It should have some textures to be a mission. All right, so the whole zombie. And let's find the diesel emission. And let's make it plus and density ten. Okay, let's see how it looks now. 00, 00, 00 00, xx creepy. But there are some graphical glitches in the origin texture. All right, so plus 10 is a bit too much. Let's make get plus seven. Let's see what happens. Okay? Okay, that's, that works. It's not perfect, but it's good enough. Now let's add some texture through Cape, so it's not plain white. That's boring. Let's find the key. Find the texture AND gate material has created it, and just change the color. We don't need to use a texture. It's all black anyway. Now let's add some gliders so he doesn't escape the world. Let's test the boundaries of this world. Delight. Make two a day. That's London. I run around and see if we can escape. This matrix, the glider, done none. So you can actually fall off the edge of the world and fall into the nothingness and keep falling. So let's add some gliders to the edge of the world so we can escape. Let's add a GameObject 3D object. We set its position and press F to go back and do it. And switch the orthogonal. Zoom out and make the cube, scale it and make it y and long. Now, so top this. Okay? And then place it to the edge of the world. Okay? My name is due. Barrier. Duplicate it. Move it to the other edge. Do the same. Rotate it again to the edge, and then duplicate it again and move it to the other edge. Like this. Now it has books glider, so you can't get through it. And now when we play, we actually won't be able to get out of the world at all. The barriers, replicas. There's no way we're ever going to get out of, out of here without a jump function. All right, Now let's turn off the mesh renders. And let's turn off the light again. So it's like, All right, we can forget to rebuild the enough mesh because we removed the plane. So go back to navigation. As you can see, the mesh is still out of the old the old plain terrain. Object walkable, bake, bake. It's gonna take some time because the terrain is huge. All right. And pretty much everything here the zombies can reach even inside the house, okay, actually the walls should be not walkable for the zombies. So let's change the object, I guess in static, not walkable and bake it. Let's tweak delayed a bit because the game is far too dark. That's all for now. In the next lesson we're going to make some tweaks. And we will add user interface. 11. Design GUI elements, create a score system and win/lose scenarios: Welcome to another lesson where we will make the game easier to use. And we will add user interface so the player can see his HB. And we will generally make the game look even better because now when the blade it looks scan of dark and Wednesday it doesn't look good at all. It looks horrible. So let's make it better a lot. The first thing we're going to do is we're going to make the boxes more visible. We're going to add another box inside them that will have an emissive texture. Without further ado. Let's just do it. So a quick one of the boxes and add a new to the object QP. Make it smaller, like oh, 0.9 and all dimensions. So it appears that's inside the box. And click on this material. Actually. Let's create a new folder. Underscore materials. Right-click. Create Material. Name it. Shiny box. And here we're going to change the parameters. So let's leave it at White. A change to metallic to do 0.3, smoothness to the MCS value. And turn on the emission. Click the color to white and make it then or eight, like so. And then just drag it to D box inside. Now let's see how that looks. Okay, and I want the box is one, get lost in the dark. But you're going to tweak the light thing also. Alright, just delete these and duplicate this box. A few times. Duplicate this. And once more. So we have enough animal. And now let's tidy up this hierarchy a bit. Create a new empty game object, call it boxes. Move it. So it's a standalone object. And move all the boxes inside of it and collapse the hierarchy. Now let's see how it looks in the game. Great. Now let's get to the script because I found a bug there going to be play the game and we press the right mouse button to make the dough force higher. Like so. Menu released the box. The drag force doesn't reset. So when you get another box and draw it is going to have the force of the previous box. So we need to reset that after every release. So let's go back to the release object function and initialize the throw force to 0. Resets after every draw. Right now, when we grab a box, hold the right mouse button. Wait for it to charge. So it will going to be get a new box and draw it. It's going to have default, the default row force. So almost none. Need to hold the button and draw it like so. Also, having two buttons for drawing and grabbing is not very good for the user experience. So let's change that to honor the left mouse button. So I'll just change it to 0. It's going to be mouse button. And that should work nicely. And we can control everything, just find there's a problem. Okay, there is if most button must put him down. Okay, so we release it immediately. We need to change it again to get another them up. Once we let go of the button, it's going to draw it. Okay. If we press it immediately, I'm going to hold it. It has 0 force. And if we hold the button, and it's going to have a force to be added by holding the button. Great. Okay. Now, there is another thing we have, B have no user interface. Currently. We don't know how much HB the player has. We don't know TO force he has. So let's add really basic user interface. But before that, let's actually clean up the hierarchy. Greater than your object, call it environment. Just draw every every environmental. Operative in their satellites, stones, the house, the shed, terrain, terrain outside of it because we're going to edit it to boast lamp. And let's grab this and move it to the environment. Let's collapse it and make a new object for the barrels or drawables through and so on and our barriers. So let's move these to our environment too. Spiral. Let's move boxes inside the drawables, like so. And the rest seems to be fine. So let's move on to the user interface. Go to the Canvas, grade the new UI image. Let's name it. H be vague, ground. Change the seam you go to D, zoom out. Move it to the upper corner. And don't forget to anchor it to the top and left corner. So when you change the screen size, it gets, it sticks to the corners. Okay, let's go into our new object. Parented to. The HB would have background to it. And let's create a new UI. Next. Hbi. Recently positions because actually the HB object was in the middle. So let's move it here and adequate again. And let's change the text right now. Thanks to change color to black. It's really basic. Ui isn't supposed to be beautiful. You can download various spikes. For example, from Guinea is an artist that makes a great assets for UI. Actually, let's use some of his skull Dui. Let's download, for example, this one. Download. And let's use one of the battles example. This one doesn't really fit the zombie world, but it's kind of a futuristic zombie world. So lets, it may be, it will fit. Let's see. Let's go to Assets. Let's create a new folder for UI. Let's drag some of these in. And Aviva will need also the pointer. So let's drag these in. Now select each of them and go to the extra type Sprite, 2D and UI, and click, Apply this felt Delhi unit there that these textures are meant for UI. Now got go to the ground, Glick source image and just choose whatever you want the UI to be. Go back to the text, change the dimensions of it so it fits the bounding box. Like so. Let's change it. Do When a 100 because this will hold the HB and click on Auto size. And we do align it to the middle. Let's make it bolt. If you have any other fonts. If you want another font. Let's change the font also, because this one looks bad. Let's go back to the guinea assets UI, and there shouldn't be a font back then it was EFN of fonts. Let's search. Kenny fonts. Oh yeah, he has a few of them downloaded and Beckett. And which one looks the best for our game? I'm going to choose the future narrow or future square. Okay, Let's just drag it to the UI. Go to Window X mesh Pro, font us as Creator. Select the future and arrow. And click Generate Font artless. Click Save As, save it to the UI. Like so. And now we will be able to use it in the HB dx. Go to HBT text, select the future narrow, stingy to MCS size to 50. Sure, that's a lot. See what we will be fitting for it. Ok. And let's see which spacing and alignment is best for it. So it seems to be okay. But the black color is weird. The white to yellow. It doesn't fit. Let's go with the white color. Let's go to the outline. And make the thickness something like 0. Do. Okay, let's see how it looks in gain. Oh, that looks actually horrible. And still beak was changed to scale. We have to change the scaling. So click on the unpooled presets. Click on the stretch horizontally and vertically, and do the same for the text. And now we're going to change the size of the barn and object that's going to change with it. So let's go and change it to 50 and 50. Let's make the text smaller. Let's experiment with it. And let's change to add occur, which is surely ginger position. So it's actually right in the top left corner. Yes, it does our age be? All right? Now let's hook the UI element to the script. So surely we need to create new Dexter friends in our mortality script. Let's go to a mortality grade, new oblique decks mesh. You go, I, HB, go to our player. It's the one that did here and drag the HB dxdt, do it. Now, each time they damage, we change the change the text. Hb dx equals HB do string. Because we have to convert the integer value to string. Play it. Let's see, Let's take damage. Okay? There is a slide that buck. The damage doesn't get updated when we die. Just change it to 0. Like this. Now let's create a new object for the force so we know how strong that row is going to be. Lads, copy this, duplicate it, change it to the floor, and name it. Like so. Move it to the right corner. Change the background to the other panel, and change the anchor of the force, the right corner, right top corner. And let's go to the delicate nieces script this time. And create the same structure of fixed mesh and call it the force text. And each time we update a frame, we will draw into D UI. Does this, this, not this, it's not very efficient. For stakes. The x equals to 0 force string. Let's see how that works. After we assign the guinea says for states to look in nieces. And let's see. I actually don't want the decimal places. We don't want it to four decimal places. So let's change it to do its F1 of gain, like this. Okay, Let's add some description to the UI. So the player 1 got confused. Let's add UI as much pro, scale it down and ride the form to the kidney. Like so. Duplicate this over with the force. And here, right force. Like so. Well, let's, let's align. It. Looks bad. It's going to be aligned to the right and this to the left and the middle. Okay. Let's add a counter for the zombies with cannabis UI. Looks much Bro. And it's going to be on a, just a, just a text. Just going for a more counter. Just for debugging purposes really saw the placeholder text. So this is going to look like this. Sum is 0. Change the font size. Let's rename it to this. And let's hug this. Do generator. So Enemy Spawner and I'm a spawn. And here let's add another variable to hold the reference to the text. Like so. And when we generate the enemies, you're going to change the text to say, zombies and number off enemies. String. Let's create a new variable that will hold the amount of enemies. Just go public, int. And a mess. Start method. You're going to make it default, DEA, number up and up to the number of enemies, enemies, number of enemies. And let's move the dx to d a bit method. So it's going to update it each frame. And we're going to access the number on each instruction, or death of the zombie. So in the enemy, and you're going to need reference to the enemy spawner. So we'll go Brave Edge. Enemies spawn. And it may spawn. And we're going to cash their friends and enemies created. And it's going to find object of type. Nm is spawn. And this way, we will be able to x as the variable, the current MS from each enemy on death. So before the Emma dies, he decrements. Their current enemies. Fly one. And this way, they UI able to get some data to it each and a mid depth. Let's assign that next to the variable here. So ambidextrous and mistakes, and that's it. Let's play it. 53 enemies or skill. One. Data seems to be a Vogue. Oh yes, because the decks here, so they think the number of enemies and not clamped on this. Grant that I means the string. Let's play that now it's going to work. If death rate. So that's eight. And now we're going to make the game a bit nicer. We're gonna change the environment. You're gonna change the lighting. We're going to add sounds. So see you in the next lesson. 12. Use sounds effects and create a sound system. (Optional: Add fog with AURA 2): One of the last things we're going to do is we're going to add sounds and sound effects. But first let's play with the lighting because the ground lighting looks really bad. So let's see. It looks now, it's dark. It's not really atmospheric in any way. It just looks bland and dull and not, not interesting. So let's make it interesting. First, let's change the the ground a bit. Because now it's flat. Generated terrain a bit. Rates all over terrain. Shoes, brush and change the size. And the fellow. And just great at these, these little bumps. So it looks more natural. Okay, now let's see how it looks. Of course, the zombies. And we need to remake the navigation for the zombies now. So let's click on bake and bake. It's going to take a while. All right. And now let's change delight. So it's more like a sunset rather than a night. Searching the intensity. The game still looks quite bad. So let's use some mature solution for this. I'm choosing the hour to its beta asset. This is outside of this free scope of our tutorial. You don't have to buy this. But if you want the again, your eventual game to look good, you to regain, to look good. Then definitely, I recommend this because that's ads, photometric light. You can add fog and all sorts of effects. The other option you have is to use high-definition render pipeline and make the fork sort of look good. And that's a free solution you can use. But if you are using the default render pipeline, which we are using right now, the hour of two is our best bet. So I'm going to add it right here. Let's go to Window Package Manager for or to download it and import it. Before we start with just change the the crosshair here. Because we imported in class time and didn't use it. So change the source image to preserve white. And let's make it bigger. Like so. Now let's use the ARRA. If you add it to a project, it creates this bundle here. And you can simply just click Reset. And it's going to create a preset for your game. Now we want to be a rather dark. So let's go with Dawn. And it's going to modify your lighting in the scene. Add fork. Let's see how it looks. Now. That's one click of a button. Now let's add some folk on the ground. So create a volume of the shape of a box. Drag it. So and so. And this box volume is going to be a fog volume. See how it looks in game. I do. It's too big. So let's pause the game and change the position of the fork slightly above the ground. Which is this, this variable is going to reset when we exit the play mode. So just copy the position. Stop the play mode, and paste the position. The fork is above the ground. And we have some atmospheric light here. She's amazing. Now, now when I think about it, the black actor doesn't need a blue jacket because we are never going to rotate him. So let's go to the layer object and change the texture. Change the texture of a zoot suit mat and just overlaid with black, like so. And that's going to hide the imperfections of the cloth. Clipping. Drew his drew his body. So now he looks kind of like a sit Lord. And now all we have to do is add some lights. Make sure that this slide right here doesn't have the volumetric settings on it seems. And also the fork is cutting off. So let's make the four wider. Like so. Be careful with this because this, our recipe takes quite a lot of lot of performance to render. Who's can see this is this looks, this looks, this looks just, just amazing. Compared to what we had earlier. This slide still doesn't have the volumetric effect. So let's go do it. Delight and add component. Our, our light. We can actually use the panel here and click convert all lights are. And see how that looks. All of the lights in the scene now our woman trick. So even this one. And this is a bit too much. So let's thank the strength. The way smaller. Yes. That looks way better. And let's change it here too. Now let's also change the speed of the player because currently he moves way too fast. You can just run around and outline zombies. So there is no pressure, almost no pressure. So slow him down. Let's go to the player object, player controller and change in strength speed to something my Kate. Let's test it. And that feels more realistic. When he's walking. Walking speed is also very fast, so make it okay. Now let's add sounds. They are crucial for the few of the game. Let's create a folder, call it the score sounds. And let's just download some sounds. A great site for various games sounds is a So let's go with some of the dark. And here we will search for Zombie and sorted by graded command 0, which means you don't have to credit the author in any way. We just can use the sound however you like. Let's download some zombie sounds. Download, drag it into our project. Now let's add, let's open the main this to zombie b sound. And go to our prefabs folder, NME, open prefab. Now Add Component Audio Source. And now we're going to just assign the zombie sound to the audio clip and play with the parameters of the audio source. So it's going to play on awake, it's going to loop. And the phloem is going to be one. And it's going to be 3D. So changes spacial blended 3D. And here you can mess around with the distance that you can hear the zombie. Let's go with nine meters. From the listener. The listener is assigned to the camera of the player. So when you go to the player object and camera, there is audio listener, which is like a microphone to the sounds in the scene. So if you play this, because the existence of the brief app of the obvious source of the prefab is way too high. So we are hearing all the zombies at the same time. So let's try this and let's try it with one zone B at first. So we can debug it more effectively. Or to zombies. Yeah, that's, that's too little. Let's go back to six meters. Play. Posit, choose one of the enemies. And let's see how we are going to interact on the graph. Okay, so we want to view the Enemy Way sooner than this. Go with 15 meters and six meters. We can mess around with the curve if you want. So let's see how does Samsung during which we don't want? So make this go down rapidly. Okay. Sounds good. While not good but decent. Let's copy this component. Stop the play mode, opening brief fat, and paste it as values. So the graph is going to get copied right into the prefab. And now every zombie in the scene is going to sound like this. Let's change the number of m is 20. It could play the audio source in random intervals. We do that by creating an audio source of friends in the enemy script. So let's go private. I will deal source, audio source. In the start method, we initialize it, Get Component Audio Source. This gets the component of the instance of the enemy. And here we turn off looping until we can do that in the prefab. Let's go back to the prefab. Prefab, the Napoleon baked or not looping. And now we're going to create a new, I enter my editor. Play random. That is going to play in an infinite loop. And the yield return new wait four seconds. And it's going to return random seconds. Random range from two to 10. And each time this loop gets any new increment, it's going to play the audio source. And now, when we start the coroutine here, the zombies are gonna play the sound in random intervals. Okay? Now let's add some background ambiance. I found a nice bank that you can get on the unit Asset Store is called free or ambiance. It's a free bag of horror sounds. So just add that to assets and go to Package Manager, search for border, and download that. All right, let's go to music. Darkness and big N is sound you like I will go with the decay fear. Let's create an empty object in the scene. Scroll it back ground. Music. Add an audio source, and just drag the fear. Do it. Make it loop. And let's find a sound. Explosion. Okay, let's go with the one. Download it, drag it into the Sounds folder. And we actually already have the prefab for the blood splatter. So we can just add an audio source to it. Assign the the headshot sound, and make it play on awake. And make it 3D. And change the sound to the same values as the zombie, so-called be. No. Let's just okay, we have to compare because there's a customer off. Let's copy this component. I mean, you'll have to reassign the sound here because it's going to override it by some. Use. Make 3D, okay, it's 2D. And signed the head should sound again. Take the play on awake again. May get louder. Actually, I notice that the force gets a little bit too low. And if you remember, we changed it after day releasing. Do the 200 five because the first row is five. And that seemed to be an OK value for this Q. Let's move the camera down a bit and rotate it. Like so. So let's add that screen, search for that sound. Male, male death, it's going to be better. That's kinda funny. Let's go with that, right? Sounds right there. Okay, Now let's add the sound to the player. Let's find the man, the mortality script. Let's go to it. And let's add two variables. One that will hold the audio clip of the sound, and another private That will hold real source of the player. That's added here. Right next to the modality script. Let's add audio source and take the plane awake. And that's also assign the sound to the variable we could just created. Now in the statement that it's just not one graded. Let's start with start method. And let's assign the audio source component. I would be all source. And when we die, we will play. We've got assign the sound as a clip to the audio source. And we're going to play it. And that's all. So once we die. All right. Okay, let's add the rest of the sounds. Let's search for flower, which I know it's such for sci-fi, for the architectonic. And he says, Let's check it in the name it do It's like Kinesis. Kinesis to hold. Let's find the techniques is script. So man, actually know surely by object that I can erase this. And the same way as before. Public, I'll do source audio clip. Or it can be cis, hold. And private audio source, audio source. So let's start method is great. Start method. And assign the audio source. Start. Like so. And let's use an array here because we're going to be using three sounds. So let's create an ad I of the gay sounds. And we're going to have three sounds. So the three sounds for is going to be like a nice Holt. And we need the sound for drawing. So an NG Okay. Client name it to documents this drove, sign it like so. And we're going to need and understand for the activation of the likenesses, like grabbing the object. So sci-fi generator. Yes, that sounds good. That like guinea say. Okay, we have that. Now, the proper way to do this is to create NM with the values with the diagnosis sounds. So create an enum. And here is going to hold, it's going to hold the sounds, the names of the sounds in an animal form. And a num is numbered with integers beginning of at 0. So the first one is against this hold. Then we have, then we have throat and attract. So draw a track. And this way, this will be 0, this will be one. And should we do? So, we will have to use a number indexes when we are accessing the array of the decay sounds. It should the B dyskinesias and the bike controller are actually fighting over the audio source here. So we're going to solve that by moving the Douglas's into a separate object is greater than m to object, call it our kinesis. And move. That leg needs a script that's could be. And based in here, combine this new and add an audio source. Untick the play on awake. And that should be. Okay. And let's move it here. Now let's go back daughter kinesis script and add a new condition. If input get mouse button down. And that's the mouse button. Then we're going to play the attract sound. So we do that by playing the sound in our audio source. And we're going to use play one chat this time because this function, it can play multiple sounds at once. So now we're going to pass it the clip that we want. That means decay sounds. It index of sounds attract. And we need to cast this to an int because this is an annual value and we need numerical value that it represents and that attract represents the value of two. So it's basically the same way if we wrote to number two in here. But because he created the NO, we can use the textural description of it to access it. So now when we press dots mouse button, the sound for attraction should play. So hold control. And for that, graves the function should object. Actually, let's copy the text we wrote. Should object and base it here. And just change it to draw. At the Holt sound. That's going to be played continuously. Whenever we hold the object, Let's assigned, we will assign the clip to the audio source. And we're going to loop it, and you're going to play it. We're going to play the whole audio source when we are holding the object. So that means when we are indirect cost method. So Audio Source play. And when we release it, then we audio source stop. Let's turn off the background music entirely. Let's change the condition here. Is get mouse button 0 and v are not holding the object. So we're going to play the attract sound. Actually we can just draw it. Actually. We can just move this to the rate cast, like so. So it's going to actually play only when you attract the box. In the next and also final part, we're going to add walking and running sounds. And we're going to build the game executable. 13. Final build: Tweak the gameplay and the sounds of walking and build the game!: The last thing we're going to add our walking and running sounds. Because currently, when we play the game and let me turn off the background music and enemies, there would be no sound for either the walking or running. So we're going to add that. First. We are going to need the sounds. You can get them on Freesound. I went ahead and downloaded some walking and running sounds. You can pick whichever sound do you like the most. There is a huge variety of sounds. As you can see, around 10000 sounds on or for walking. So I went ahead and downloaded some of those and put them in the Sounds folder, running sound and walking sound. And now we need to add an audio source to the player object. So let's add a component audio source and turn off their play on awake and turn on the loop because the sound of the walking is going to be looping. And so we're going to be running sound. Now let's go to D by a controller. So let's first add some variables. Let's add the variable AudioClip that will hold the walking sound. Duplicate this line by Control D, limit the running sound. And we're also going to need reference to the audio source we just created. So audio source. I will do source. And we will also need to check if we are working. So we're going to create a variable. Boole was walking, and we're also going to set it to false. And now let's go to the start method. And here we're going to initialize the audio source component. Audio source. It's just gonna get the reference to the audio source component. And now we will need to edit the move function. First, let's save the information about the if we are walking or not. As good, a new boolean is currently walking. And let's just copy this condition here that we used before. This is also a Boolean and it returns true if we are walking, if you are moving and force if we are not. So assuming that here. And as you can see, we need a reference to the vertical move animals onto move, which is not assigned yet. So let's move these, these right here. And now, let's create a condition. If this currently walking and and it was not walking. So that means we just started walking. We will assign. The Walking sound to the audio source clip. And we're going to play it and play the sound. And else if b, where walking. And we are not anymore. So it means we stopped vlogging. We will just stop the audio source completely. And now let's go down here. And let's assign the was walking. At the end of the frame, we will use the same information as previously. And this way, this inflammation will contain the state of the walking at the end of the frame and this right here at the begging at the beginning. So we will be able to compare these two. Okay, Now let's assign the sounds. So that's running and walking. Running or walking sounds. So walking, walking sound and running sound. Let's try it. We are able to do code the running sound. And we do that by checking the animation state. And to be already have the animator reference here as seen here. So we are going, we are going to utilize the information from the animator. Because the solution we have right now doesn't allow us to effectively check the running state other than by the animation state. So let's use an amateur get current animation state info in the first layer. And let's check if the name of the animation that's currently running is run. And if it is, we're going to check if the animation just started. That means that we will start playing the running sound. Let's do it again. Get my door of state NFO. And unfortunately, we can't use the frame numbers. So we have to use our mice time, which checks if the animation, the time of the animation. So if the animation is under 1 second, so that means just started. I going to assign the running sound to the audio source clip. And we're going to play it. That is going to be a few duplicate frames here. It will be good enough for the game. And let's do. Else, actually else-if. And let's copy this. And we will do if the current animation is, is walking. And it's also could be this. And if it is, then the sum is going to be working sound. Okay, so that's it. Now let's try how it looks. And that's it for the sounds. I'm going to actually add a two week that will change the text zombies to u1 after it's a 0. So let's go to NMS bone. That's last thing we're going to do. And the game will be complete. Sure, Let's do it from the enemy. And here, if the enemies spawn current NMES equals 0, then we will call function one, which isn't graded yet. So let's create it. And here we are going to change the zombies text to u1 or you defeat it. Like so. In this abutment that so let's do apparent enemies are greater than 0. We're going to update this text. Otherwise, we will set it to you defeated vdc. But one other thing I want to fix is the drag force is go to kinesis and change their door force to then. And down here when it resets our sought to 10. Let's died out. Stuart's, they'll week. Still weak. Let's do something like 25 then. It's going to be more fun. It will force 25 astringent here. Rate of the cell again. And now again actually. So NANDA, background music. I'm going to make it even more silent. And on and on, and change to animate, count to something like 30. And let's play the final game. Flash is almost not being heard. Must go through a brief apps and click the blood splatter, open prefab and change the audio source volume and move it. Like so. Let's save it, run it. Okay, still not enough. So let's go back, but splatter. And it's changed the max distance to 30. Okay, so that's it. And now we can export the game, the final product, just go to File, BuildSettings. Make sure here are all your scenes. In our case it's only one scene, the sample scene. So click Add Open scenes. Then select your target architecture, in our case windows. And click belt, then select a folder to what you want to export it. I'm going to create a new folder, tutorial, export, and export it and build it into this folder is going to use only the assets that are actually used in the game. So the resulting executable belt should be fairly small. Let's see. It actually has 243 megabytes, Okay. Okay, so that's all. I hope you enjoyed the tutorial and hopefully see you in the next one.