Hi everyone. I am Jeremy Gibson Bond and welcome back to The Unity Certified Programmer exam preparation course. In this video, we're going to be talking about Unity Networking. In particular, the high level API that does a lot of work for you as opposed to the low-level API that's included that allows you to write a lot of your own, like direct network calls. Now, it should be noted that this type of unity networking is eventually going to be deprecated. In a blog post on August 2, the development team said that they are going to phase out unit which includes both the high-level API and the low-level API and bring in something new starting with version 2018.4 of Unity. So looking at this chart here, you can see that through the 2018.4 long-term support release. They're going to provide critical support and updates and fixes to the high level and lower level APIs through the beginning of 2021, and things like the relay service and matchmaking service are going to continue into 2022. The new feature is going to start arriving at the end of 2018 and will be part of unity for the foreseeable future. However, that being said, high-level API is still an important thing for you to know for the exam. So let's take a look at a tutorial that covers a lot of the material in the high-level API that is worth knowing. So first I'm going to apologize for the kind of funky layout of Unity here, but I want to do something that allowed us to see both the networking example as a build and the version running in the editor simultaneously. So here in my build, I'm going to click ''LAN host'' and here is my little character and I have these kind of ghost things and I can shoot them and their health will decrease and they will eventually disappear. Now, I can run in my editor and I can click ''LAN client'', I realized it's very small here but I can click ''LAN client'' here and now you can see that there's a second character, you can see it's kind of stuttery but the one I'm controlling in the client which is any editor is blue in the editor and white in the build. Conversely, when I'm in the build, the one I'm controlling is blue and the one that is in the editor is white, so, I can shoot and you'll see that it will destroy this object and then the player characters will be re-spawn at their initial spawn point whenever their health goes to zero. So, there you go, that's it working. Now let's start to dive into how this actually works. Now, the original tutorial you can find by going to Google and searching for ''unity multiplayer networking tutorial''. It should be the top link. Following that link, you'll see this 18-step multiplayer networking tutorial called ''Creating a Simple multiplayer example'' Now, there are certain elements of this that are a little bit dated and I've updated them in the version that you can download from Coursera of the project. Returning to Unity, the core element that runs everything else is The Network Manager, and our network manager game object has two different components on it that are critical. One is The Network Manager script and this is part of the high-level API that does a lot of work for you and this manages the network and also spawning players. You can see here in spawn info, there's a ''Player Prefab'' and that is anytime a new player joins the game, that is the prefab that has spawned for that player. Below this is information about how the player is spawned Round Robin as it just chooses between different spawn locations, we'll talk about the spawn locations in a second and then there are registered spawnable Prefabs. These are Prefabs that are registered to be able to respond on the network and the two that we have are The Bullet and The Enemies. The second core component here is The Network Manager HUD script and this is just a basic UI to allow you to easily get into games for testing. So that's what you saw on the top left corner while I was testing. This allowed me to run the build as a host which means it's both a server and a client and then in the editor I could run as a client and connect to that host. In general, you're going to want to replace that HUD with your own HUD for any games you would actually release. Now I said I would talk a little bit more about this Round Robin player spawn method. You can see here that there are two spawn positions, one and two. And each one has a network start position script attached to it. This is another built-in, high-level API thing that allows The Network Manager script to automatically spawn players at one of these to spawn locations. If the player spawn method is set to Round Robin, it we'll just alternate between them. It will kind of go so that all of them are used before any of them are reused. The other method is Random, where it just randomly picks from one and it could actually spawn two players directly on top of each other. The player game object is where the bulk of the important stuff happens here and you can see that it's this kind of goofy little capsule with sunglasses and a tube gun kind of thing. Each thing that you want to be part of the networking, to actually be shared across the network, needs a network identity script and again this is something you just kind of drop onto it. Local Player Authority allows the local version to have authority over where this instance is and so that is checked for the player. On the other hand, if you look at the bullet, you can see that server only is not checked and Local Player Authority is not checked for the network identity. Meanwhile, something like the Enemy Spawner which only is meant to exist on the server and only exist to spawn multiple enemies that will be shared by all the clients and the host is server only. That means that the Enemy Spawner will only run on the server. On the other hand, something like The Bullet does not have server only or local player authority checked. It is just a kind of shared resource across the network. Going back to the player game object, there's also a network transform on the player and what that network transform does is it shares the transform information, you know, the rotation the location, that kind of stuff across all of the different networked instances of the game based on who has authority. In the player instance, this player has authority and then you see what the network send rate, 25 times per second, that information is sent out to everything else on the network. Now, this gives you that kind of Jagged movement that we saw. That's because it's very basic networking at this point. There are lots of things you can do to smooth that information to interpolate from one frame to the next and update based on a prediction of where you think that the player is going to be. One way that you could do this kind of prediction is by looking at the past, looking at the past two or three locations that were sent and using that to kind of interpolate where it should be next and move towards that next position and then, kind of, tweak it over time to adjust to be correct. Again, it's not perfect, but networking is never perfect and it's up to you to make it work in a way that works well for your game. You can see here, that instead of extending mono behavior it extends network behavior. That allows it to use all of the built-in networking things like isLocalPlayer that you can see on line 11. There, if we are not the LocalPlayer, the update is not run. This ensures that only the LocalPlayer will execute the code on its local client and then that information will be sent up to the host to be distributed to all the other clients. If you did not have this isLocalPlayer check, then the input for one character would actually alter all the other player instances in their version of the game. Now, you'll note on line 24 that we don't just call a fire method we call something called CommandFire. Now, CommandFire or CmdFire is a command and in HL API networking, a command means it is a method that is called from a client, but run on the server. So, when CmdFire is called, the server generates a bullet, sets its velocity and spawns it using networkserver.spawn to spawn that across the network and then destroys the bullet after two seconds. We're going to talk about that bullet in a second, but first I'm going to look at this OnStartLocalPlayer. Again, this is part of the network behavior that we're extending and this is only called when the LocalPlayer starts. So, when the instance that I'm controlling on my client or host is started and it gets the material of the mesh renderer and colors it blue. So, that to me I look blue, but to everyone else I look white and to everyone else they look blue, but to me they look white. Now, looking at the bullet here in Unity, if you look carefully, you'll see, of course, there's a network identity and network transformed because there's a shared object it needs a network identity to be part of the networking and needs a network transform to have that transform information shared across the network. But, its network send rate is zero and the reason that its network send rate is zero is because when we do the network spawn, we spawn the same bullet on all of the clients and there's nothing changing and it's not like you can guide the bullet or change its velocity or direction after it's fired because it just continues given the same direction and velocity that it started with. We don't ever need to update it, which saves us a ton of network trafficking. So, that's kind of a trick to think about when you're dealing with networking yourself and things like bullets that there might be lots of. Now, you'll notice on the player that there's also a health script. This health script is responsible for managing player health and managing that health bar above the player's head and then when their health reaches zero, resetting them back to their original spawn point. When a bullet hits a player, the simple bullet script looks for a health component on whatever hit or a parent game object and the reason its GetComponentInParent is because it could hit things like the sunglasses or the frown or something like that and right now if we did not have GetComponentInParent and the bullet hit the sunglasses, it wouldn't actually get the health component. So, we need to GetCompartmentInParent, if there's anything that the bullet can hit other than the player capsule. So, it gets the health component of the parent and then it tells that health component to take a certain amount of damage and I realize this 10 is hard-coded in, but that's how it was in the tutorial. So, I went ahead and stuck with it. Now, you'll see here in the Health script, that the first thing that happens on take damage is we say if it's not the server, return. Now, the reason for this is because every client and the server all have a bullet moving at the same rate and that bullet will hit this player at the same time across all of them. But, we don't want all of them to decrease the health of the player. We only want the server to have authority over that. So, any of those instances where the collision happens, if that instance is a client, it just says, oh, that's not my problem. So, then, on the server, currentHealth is decreased by the amount that was passed in and if currentHealth is less than or equal to zero, then if destroying death is true, destroy the game object and destroy on death is true for the enemy characters, but not true for the players. So, for a player, the player's health is going to be reset to maxHealth and then RpcRespawn is going to be called. So, what does this Rpc thing. Looking at the remote actions entry in the Unity manual, you can see that a Client RPC call is something that goes from the server to the client and that's exactly what it does. Anything that has the attribute client Rpc and starts with the letters Rpc and the method name, can be called by the server and run on all the clients. So, what happens is that playersHealth reaches zero, the RpcRespawn call goes out to all the clients and the one client that is the local player picks a spawn position to go to and moves the player to that position and then because that client has authority over the location of that player, that is then sent out to the rest of the client attached to the game and to the host. One more cool thing to show here in the network behavior on health, is you can see here on line 12, SyncVar(hook equals OnChangeHealth and that's for the currentHealth public integer. So, anytime currentHealth changes, then the sync of that as part of it, calls OnChangeHealth, and you can find the OnChangeHealth method a little bit further down and that just sets the size of the health bar. So, that ensures that anytime the current health changes, is syncs across all instances and then each instance calls OnChangeHealth. One cool thing to pay attention to in the EnemySpawner, is just like OnStartLocalPlayer in the player, on the EnemySpawner, we have OnStartServer and that is only called on the server when the server starts. So, here this just sets up random positions and rotations for the enemies that are spawned and spawns the initial four enemies. The final script in here is the addFollowCam script. This is on the player and if it is the LocalPlayer when it starts, it'll go ahead and grab the main camera and put it behind the LocalPlayer as a child of the LocalPlayer's transform, so that follows the LocalPlayer around. That just makes it a little easier to aim and stuff. The camera in the original tutorial was just a static camera that sat there and it's very difficult to aim. Of course, instead of just start, we could have OnStartLocalPlayer for this rather than just checking to see if it is the LocalPlayer as part of the regular start that would work just fine. So, that's a basic intro to unit Unity networking and my hope is that this will help guide you down the path to learn all the stuff that you need to look into before you take the exam. I hope you enjoyed this video and look forward to seeing you in the next one. Thank you very much.