Godot Networked Multiplayer Shooter Tutorial #2 - Setting up Players

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
okay first you want to go navigate to the google drive link that i have in the description you want to download all the assets i'm just going to import them in just characters and tile sheet and that's all we need now these are kenny's assets he makes some awesome assets all i did was upscale them because they were at super low resolution and i just have them on the google drive so definitely go check out kenny now you're going to want to select each of the textures and go to import and turn on mipmaps this basically tells it so if we scale the sprite it will dynamically set up the pixels you know it just makes it makes it look good if you resize the viewport or you zoom in the spray and then we're gonna also set this as the default for texture that way we don't have to keep setting that for the textures and just select the tile sheet and hit mid maps so all new textures will automatically turn that on next go to project project settings we're gonna go input map we're gonna add some action so add right left up and down now right it's gonna use d left is gonna use a up is gonna use w and i i think you guys know where i'm going wasd now i'm also gonna use the arrow keys so right right arrow key and i'll just repeat this for all of the other keys okay so now that we have the input set up you can close that and we're actually going to make in our scripts so right click and cut file system make a new script we're going to call it global and we're going to open the script we're going to make a function called instance node it's going to take a node in the parent now in this instance node we just make a node instance reference of the instance node then we tell the parent to add the child of the node instance and then we return it so we can access it later now we're going to add another function above it this is going to be instance know that location it will take a node apparent and the location it will get a reference to the instance node using the node and parent arguments then it will tell the instance node global position to equal the location vector and return it so we can actually access it again so this is essentially just going to make everything easier when we instance nodes that way we can just say instance know that location next we're going to save global go to project project settings we're going to auto load we're going to autoload global that way we can access it in any script and just press add this will come in handy once we actually start instancing players so save this now we're going to add a new scene we're going to make this kind of mac body today we're going to rename this player then we're going to add a sprite now in this spray you want to drag in your characters.png this will just be the entire spray sheet of all the characters and then turn on region enabled so we can select a certain one and you can go in texture region to manually select yours you can turn on snapping and say grid snap 256 by like i don't know 250 you can do this and select your character um i actually just have the values right now so i'm just going to import what i used i used 512 on the x 1 500 on the y 256 on the width and 250 on the height and it's a little offset so what i'm going to do is i'm going to go offset and i'm just going to do 16 on the x and negative 6 on the y and this will basically center it also the sprite's a little big so we're just going to make the scale 0.75 0.75 then we're going to add a collision shape to the kinematic body we want collisions we're going to set this shape to a capsule shape and then for the radius we want 40 and for the height we want 33 and that's basically our hitbox next we're going to add a tween and we're going to add a timer now we name this timer to network tickrate and we're going to set this weight time to 0.03 and we can set the auto start now in the player we're gonna add the script just have it as player.gd then we're gonna select our timer connect the timeout signal back to the player and let's um let's define some variables above so i'm just gonna have a speed as a constant it's gonna equal 300. now i'm just gonna set up a velocity variable and i'm gonna get a reference to our tween in the process function we check if we are the network master i'll go over this later um we get an x input variable which is our right subtract our left key so it converts it from a boolean to an inch so zero or one one being press zero being not pressed and subtracts it from the other one so if i press left and right they're gonna equal one and one which is one minus one which is zero so cancel it out if i just do right it will just be one next i'm going to get the velocity which is just gonna equal the x input y input normalize it i'm going to tell it to move in slide with our velocity multiplied by a speed and look at the mouse position now what network master means is whenever i instance a networked object i will always set the network master using an id which is your current go.tree unique id which is generated once you actually connect the server or you create a server using a multiplayer e-net and this basically checks if we are the current player so we'll be able to move around if we are the current player if we are not then we won't be able to move the other players because we're just controlling our certain player so we'll compare the scene tree and then they'll say okay this player was instanced with the unique id one five six seven so those match up which means we are the current player controlling this let's just make sure that we can't move enemy players around with our own inputs let's get into some of the network codes so up here i'm going to import a puppet position variable that's just a puppet variable and it'll use the puppet position set puppet basically tells godot hey this is a variable that we're going to be changing over the network and i'm using a set get function so let's import or set get it basically so once we change our puppet position it gets the new value and it just updates it with a new value then we're just going to tell the tween to interpolate the global position to the puppet position so essentially let's say you receive packets like every 0.25 seconds so there's going to be a space in between that frame where you don't receive a packet and the player will sit still and then he'll teleport to the next position and that doesn't look that good because it looks like they're lagging and they are lagging but we're gonna try to compensate for that and make it look like they're not lagging by interpolating between those two positions so it'll just make it smoother and the players will jitter less when they're moving around now under the network tickrate we just want to say if we are the current player that's being controlled we want to send out our position variable so this is basically saying change our puppet position variable and update it with my global position well that's basically what our set does it will change the variable that you have as a string it will update that value with whatever value you have right here and the reason why we're using unreliable method is this will send out packets way faster than the reliable method now unreliable means that we're gonna actually be losing packets so i could be sending out tons of packets and maybe like let's just say five percent of the packets are lost right that would mean we have less data but we are still saying packets at a rapid pace it doesn't matter if you do a one-time thing let's say you try to buy something in the shop you want to use our set because you want to make sure that packet is received on the client's end because if you use unreliable there's a chance that packet won't make it the reliable method will check if the client has received it and if it hasn't it will just keep sending out packets uh at a slow pace to make sure it actually receives it now the data packets are not encrypted so don't send login information over the network if you're gonna do that you're gonna wanna use dtls encryption i won't get into that for now we're just going to be using unencrypted packets now we want to receive the rotation of the player because we're looking at the mouse position so we want to send out our rotation and we want to have all the clients receive it now to do so we want to do another puppet variable up here and we'll just have it at 0. now under network master just do else so you're just going to add this code if we are not the current player then our rotation degrees will interpolate the rotation degrees and it will interpolate to the puppet rotation value at delta multiplied by eight i just did the delta so then it's consistent if the user end is lagging it doesn't really matter i just left that in there just in case and this will make sure that the rotation will also be interpolated the reason i'm not using tween is because we're actually going to be checking on this tween to see if the player is moving or not later on so that's why we're just going to be using the slurp right now now under the network tick rate we just want to r set our puppet rotation with our rotation degrees value so this is basically all you need but i'm gonna go take it the extra step you're gonna have unreliable connections when people play games like when you tell them you're gonna play your online multiplayer game they're gonna expect the net code to be good and they're going to expect the experience for the networking to be good now i'm not going to be giving you the best net code because obviously i'm not an expert at this i just learned this and so i'll be giving you my best net code but it's going to be far from the greatest that being said i'm going to take an extra step because i haven't seen the other tutorials do this and we're going to take another step further in the lag compensation so rather than just interpolating the position we're actually going to define the puppet velocity variable and we're going to receive the last velocity so this is almost like extrapolation where we're going to be guessing where the player is going to be next so with this puppet velocity under this else statement this is what we're going to be using for the velocity so when when we are not the current player and the tween is not active meaning the player is not moving to another position meaning a packet hasn't been sent we're not interpolating to the next position then we're gonna say to move and slide the last received velocity variable at our current speed now the last thing we have to do is we have to send out our velocity variable so just under network tickrate we're just going to put that there also we could technically throw this in the process function i just didn't do that because there's not much reason to send 60 packet every second because packets aren't gonna defer that much so i'm just gonna keep it optimized and i'm actually that's why this value is like 0.03 so it'll send out a lot it'll still send out the packets quickly it just won't be that much packets compared to the 60 that you'd send every second and for other networked objects you can change the tick rate and make the wait time a bit longer just to optimize and prioritize certain objects over the networking but we're not going to get into that we're just going to be using this value so now we receive our last velocity and if we are no longer if we haven't received the next packet for position we aren't interpolating to the last position then we're actually going to start moving the last recorded velocity so if i was moving diagonally let's say they haven't received in my next position packet in like a second then my character will keep moving diagonally until it receives that next packet then it'll correct its position but this just takes the extra step in the lag compensation so that's our player we can save it save this player.tscn and we have all our entire player object done also one more thing before we actually get into spawning in the players in the lobby you want to go to network down here and i actually i screwed this up last episode so i did the ip address begins with 192.168 right but sometimes there's a virtual address like um in virtualbox or virtual machine that uses a dot one address uh it'll be your device i p address bill end in dot one meaning it's a virtual address and this will not work in our case so make sure you do and not id dot ends with dot one this will make sure that we are actually getting a physical wi-fi address and not a virtual one sorry i left it that last episode i screwed that up but make sure you have that in here all right now we can get into lobby spawning so go back to the network setup scrape all right so we're going to find what our player is up here so at the top so we're just going to get our player loadplayer.cs again also one more configuration thing before we actually start instancing players i'm going to make a new scene we'll just make this a node just a normal node and we're going to call this node players now we're going to save this and just save as players.tscn now go project project settings auto load and autoload the players.tscn and we'll just name it player the reason why we're doing this is i actually i'm not going to destroy a player in this game i'm only going to destroy a player when they disconnect from the game this is going to make things a lot simpler so we're not constantly having to respawn in players in the lobby and all this other junk this will just make it simpler for us technically we can destroy the players i'm just going to make this easy and i'm just going to throw them into an auto loaded node that won't be set upon changing scene right now we can go to network setup now we can define our instance player function it will take an id argument and it'll say player instance equals global.instance node.location remember we defined that started this tutorial and global will instance the player which is right here loadplayer.tscn and the parent is players which is that autoloaded node right here and that will make it so then the players don't get reset whenever we change a scene then we're just going to spawn in the players at a random value between 0 and 1920 and a random value between 0 and 1080 which is our basically our game size so we'll just instance a player at random location uh we'll we'll set up spawn points later that way players don't actually spawn on top of each other because they'll be colliding with each other but for now we'll just use randomness next we're going to set our name to the id that we instance our player at and set the network master at the id which will tell the player hey this is which client we belong on and this is the client that's controlling us all right now all we need to do is go in this function player connected and say instance player and use that same id argument that tells us the player with this id has connected will instance the player with that id right here and then when the player disconnects we just want to destroy it so we could just say if we have that node and we search the id so if players if this auto loaded node players this all loaded node players has this current player id that we're looking for then we'll get that player and we'll destroy it when they disconnect also on the create server we're going to instance our player because when we host the game we want our own player to be instanced and we're just going to use the get tree dot network unique id that will basically return the id of our current network tree this will just return their network id which will be used to instance the player and so whenever player gets whenever a player connects it instances a player whenever a player disconnects we just destroy a player and whenever we create the server we create our own player because the host wants to play too unless you're using a dedicated server system then just don't worry about this line of code because you are not going to want a dedicated server to have a player in we need one more signal so we're going to do git tree we're going to need one more signal in the ready function so we're going to connect that we'll tell the scene tree to connect connected to the server to ourself and i'll just put this above the instance player method and i'm just going to call a function underscore connected to player and then this is the connected the server function and i'm going to tell it to yield 0.1 seconds now this isn't this isn't a good solution in any way but i just do this because the spawn location system will actually you'll have to make sure that all the other players are spawned in or else the spawn location system might spawn this player at the wrong location so i just made it so we wait 0.1 of a second and we're just going to instance our player once we connect the server it will instance a player for that for this client so so once a client connects to the server it will instance a player for that client and whenever you host a server instance a player for you and then it'll get all the other players that are connected and instant styles so that's everything now we can actually test the game so let's start let's run the game right here oh also i accidentally put the signal twice to connect to the server so just use just use one i forgot to uh import the signal in here so just make sure you only have this once and then you should just be able to run the game okay so that's everything and i'll just run another instance to go down if you ever see an error that's saying it can't connect because the port is not open or something in the output you can just go to editor edit their settings scroll down go to network debug and just change the remote port you can change it by one or down one it doesn't matter so i'm just going to run the project and then we have in our window and i'll say okay i want to create server on this end and then on this end i'm just going to enter the ip address the server which will be the same because we're on the same computer and there you go our player has spawned in and they're able to move around our rotation is also transferred now i do have it so the rotation does stutter a bit like you'll see it flips around a lot and i'm going to look into that and see if i can fix that so let's test it with the third client make sure it's able to spawn in all the other players that are already connected and that client's right in and you can see they collide with each other and they can move around so i can exit out and the clients will disconnect now i'm just i'm just going to show you the lag compensation if i go to the network tickrate i can artificially i can almost artificially introduced lag so let's say we're only going to send out this function every one second so this is very extreme in the latency and so this is a very extreme example of bad latency and we'll see how our lag compensation system does so let's run and hit join server so now we got three players now this is one second delay so i'm going to move this player right here let's see i'm moving diagonal and i stopped moving and you can see it corrected itself because it didn't receive that packet for a while so it just kept moving in that direction right and so it's almost like it's creating more data except it's just using the reusing the old data and it's just gonna wait for the next packet so without this lag compensation system it would look a lot worse than this he would just basically be teleporting it looks a lot worse right it's like the other one was still like unplayable but now this is like literally unplayable like you cannot play this at all
Info
Channel: PlugWorld
Views: 10,862
Rating: undefined out of 5
Keywords: gamedev, godot, game, development, design, multiplayer, network, networking, shooter, topdown, io
Id: fE6GNBkeey8
Channel Id: undefined
Length: 16min 46sec (1006 seconds)
Published: Thu Feb 11 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.