UE4 - Advanced Networked Movement Tutorial (Sprinting & Wall Running)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys and welcome to my tutorial on network to character movement we will definitely get into it here pretty quickly I just want to say a few important things up front so first of all this tutorial is going to be slightly different than most my other tutorials I actually already have all the code written and I'm going to kind of go through it with you guys and explain to you what's going on and the reason I did it that way is because I actually tried to do it live coding before and I ended up several videos in several hours in and realizing that this was way too complex to do in a live coding fashion where I showed you where I was like literally writing each line of code so what I decided to do was provide you guys a download link to the full source code so you guys can download everything they'll be in the description of this video you down the whole project including all the C++ code that goes along with it so that way you can kind of follow along as I'm explaining it so I highly recommend that you probably don't try to follow along with typing everything because that's just gonna be way too much I probably took them in just got sitting back and absorbing the information because it's gonna be a lot of code but it's also gonna be a lot of information I'm gonna really try to explain to you guys how networking works inside of unreal I even have a little presentation for you guys that I set up it's not too long it's mostly just pictures but I think it's gonna be super helpful because there's a lot of things that you need to understand like a lot of terminology that you need to understand about networking inside of unreal before you can really even begin to understand the code so the flow of this tutorial is basically going to be I'm gonna do a few slides of the presentation just to explain some very basic networking things and then we're gonna hop out and I'm gonna show you how actually the wrong way to implement character or network character movement I'm gonna show you like a wrong way to do it and the reason I want to show you the wrong way to do it is well for one it's gonna be very quick so don't worry about it wasting a lot of time but it's going to show you guys the way that a lot of tutorials will explain how to do it and there's a lot of tutorials on how to do Network character movement but they all explain it in a way that actually doesn't work in a real-world situation so I'm gonna show you guys how they do it and I'm gonna show you exactly why it doesn't work in a real-world situation and then once we have that all the way we're gonna go back to the presentation and I'm gonna explain a few more in-depth concepts about networking and then we're gonna jump into the C++ code and I'll explain to you the correct way to do it and how that works and that's gonna be the really complex part but I'll do my best to explain explain it as we go so let's hop out of this real quick we'll come back in here and I'll explain things more once we get past the first few slides of this presentation but I know you're probably thinking oh no not a not a presentation but I promise is gonna be super helpful and it's very quick and it's mostly pictures so just bear with me if you don't if you already know this stuff just it's gonna be really quick but for anybody who doesn't I just want to explain it so the way networking works in unreal and I just shamelessly stole these slides from an unreal presentation point everything works well in general is that you have one server and you have a bunch of clients that are connected to that server and the server talks to the clients and the clients talk to the servers but you'll notice the clients do not talk directly to each other they only ever talk to the server so that's a really important distinction to make next there's two types of servers there is a listen server which you can see demonstrated here and that means that it's a server plus somebody playing on that server so a good example of this is like a lot of old-school games like Halo like old Halo 2 8:03 or just older games on the computer where you would host a game and you would have you would essentially be the server or you would be the host and then your friends would join you right so you'd be hosting that game locally that is what's referred to as a listen server and the other type of server is a dedicated server and that's what a lot of games now like the newer alright pretty much any newer game like fortnight pub G then multiplayer and Call of Duty like whenever you connect to a server you're connecting to a server on the cloud somewhere and there's nobody actually playing on that same machine it's just a server that's running as the server so that's where they get the name dedicated server it's a server and it's only the server there's nobody else playing on that machine so again there's listen servers and there's dedicated servers and both of those are supported and unreal ok so we're gonna hop out of this real quick and go back to unreal I just wanna show you guys briefly how to kind of set this type of stuff up the listen server and the deck edit server so by default if you come here it will look like this you'll have number of players set to one and you'll have run on dedicated server will be unchecked so if you just run this this is how you would probably been running your game from you know since you've downloaded unreal if you've never tried to do networking stuff it just creates a new window and you just have a little single-player game but if you want to run in a network mode you can hit this drop-down and you can change this to two and if you change this to su and hit play you'll see it creates two windows for you one of your going to left and one on the right and by sending it the two it's actually creating a listen server for you which again a listen server is a server that has a person playing on it and then it creates a client and if you look up here at the top you can see the name of this window is called game preview server and the one on the right is called game preview client so the one on the left here is actually the server it's a listen server and the one on the right is the client and if you set it to something higher than two then you're still going to get only one server but then you're gonna get more clients so here we would get one server and two clients and I think can go all that before yeah so you'd get one server and three clients but I'm gonna keep that too and if you want to test with dedicated server then you would check this dedicated server button and then you can see I still have to set to two if I go ahead and run it you'll see now instead of having a server on the left I have a client on the Left and I also have a client on the right so now instead of a server and a client I have two clients and they're connected to a dedicated server and that dedicated server is like behind the scenes you can't actually see it it's being handled by the engine so that's how you test with listen servers first dedicated servers you can do it all through this little drop-down button next to the play button okay so now that we have that covered let me show you guys briefly how a lot of people are a lot of tutorials will show you how to implement Network character movement and I want to explain to you why it's wrong so I'm gonna go inside of my third person character blueprint and I haven't modified anything about this blueprint at all other than I changed the capsule component to be a little smaller I just set the radius of it to like 30 and I'll explain why I did that later but it's for the wall right it just makes it a little bit smoother we're actually said to 30 for me to set it to 30 so I just make the capsule component a little bit smaller but the main thing I did here is I've added these two blocks code down here so you see at the top here I have in green the correct way to do it which we'll cover in a little bit but the thing I want to focus on right now is this red section down here which is the incorrect way to do it so the incorrect way to do it is something like the disks it's only these three little events so it's not that big alright so inside of here we have this input action sprint event and when this gets called or when the when the Sprint key is pressed it calls set walk speed and you can see in parentheses I have server so it's calling this event down here and this event if you look on the right here I have set to run on server so this event is going to run on the server and it's going to call on set walk speed which is this down here and it just passes through the max walk speed and then after this it also calls onset walk speed locally so basically what this is doing is it's saying when the Sprint key is pressed tell the server that we want to set the max walk speed and then also set the max walk speed locally on ourselves so that way it's updating the max walk speed locally and it's updated on the server and then the opposite happens pretty much when you release the key it sets the max walk speed down to 300 and it tells the server to do that and then it does it locally on our machine as well and again this is the way a lot of tutorials will show you how to do it and if you go ahead and you run this it's gonna actually appear to work and that's why a lot of the tutorials out there are like you know this is the correct way to do it and they in the tutorial because they show you that it's working so you can see if I press shift you'll see I'm sprinting on the client and on the server and as I let go everything works fine I go for sprinting they're not sprinting but the problem here is that you're testing in a totally perfect environment if you would there's absolutely no latency involved because you're testing totally local on your machine and as soon as you introduce any sort of latency to this which is gonna happen once you you know ship your game and you have multiple people you know one person playing you know different states or even across the street you're gonna have some amount to latency like you're gonna have some amount of ping in your game and once you introduce any sort of ping into this solution it stops working so there's a way that you can actually do that in unreal where you can kind of simulate ping and say hey act as if there's a you know X amount of ping and to do that you can do it inside of the default engine ini file and if you don't know where that is it's gonna be in your project solution so if you find your projects or if you find your project really guy called my character networking ya and you go to the config folder and then you go to default engine ini if you right click and edit this with notepad or some sort of editor this is your default engine on ini file and I've added these three little chunks here and again this is all going to be in a download link in the description of this video so don't feel like you have to copy these by hand but inside of here there's a few things the main one I want to focus on right now is this top one packet simulation settings and you can see this is a stands for packet lag and currently I have it set to zero and that's what it is set to by default if you don't have this in here but let's set it up to something like 500 so what this is gonna do once I restart the engine it's going to simulate a essentially a 500 ping and I know 500 is really high for a lot of games news normally you don't have anywhere near a 500 ping that's considered like really bad almost unplayable but it's good to always test with the number I always use 500 as my number it's always good to test with an extremely high ping because if you test one of the with an extremely high paying you're gonna find issues that you might not find otherwise and you're essentially going to be testing at worst case scenario all the time so if it works at 500 ping you know it's going to work even better at a normal ping which is closer to like you know 50 or maybe upwards of 100 so if you're doing anything with networking you always want to make sure you have this set to 500 when you're doing testing or at least some high number other than zero so that you can catch these bugs so I'm gonna to 500 and I'm going to come back here and we're just going to do a restart of the project so I'm going to close it down and restart it and don't worry about Visual Studio right now I'll be talking about all of this later just focus on the blueprint stuff right now so when it restarts you'll notice there's going to be a significant amount of lag or latency between the server and the client so if I go ahead and run this now I'm gonna move that one over here and it's not over here actually let me run it without dedicated server so it's a little bit easier to demonstrate so I put the server on the left and the client is on the right all right so you should notice right away when I jump on the right you'll see it takes 500 milliseconds or half a second for it to jump on the left and that's because we added that 500 milliseconds to the default Engine III so now it's simulating as if there's a 500 ping and you'll notice if I walk everything works fine but as soon as I start to sprint you'll notice things go downhill very fast I've started jumping all over the place a lot of people refer to this as rubber banding but you can see on the client I'm not having a good day and even if I wasn't some using something I saw a spider paying ego I've had 50 ping in here it would still be doing this it wouldn't be like quite as horrible as it is right now but it would still be totally unplayable in your game so this is a very important thing to know when you're doing network code is to test with this packet lab because if you don't do that you're not it's not it's just not going to work when you put it into a real-world situation like you can see here so I wanted to explain that as best as I could because a lot of people fall into that you know fall into that problem without even realizing it so before you ever start doing anything networking related in your game make sure you enable this so you can test with ping all right and then briefly I'll just cover the other things in here to be perfectly honest I don't really understand exactly what all these values are used for I just I just found these values through like googling and some trial and error but the ones that I really know what they do are these down here and these set the server tick rate I have mine set to 120 which is might be a little high you can set down to 60 but this is where you would set your server tick rate obviously the higher the tick rate of your server is you know the better the game's gonna feel and and and work for you but the other ones honestly I don't know what they'd they do too much to be honest I know they have something to do with like networking and the update rate of things and it these values seem to work the best for me so if you just want to copy these that's probably the best advice I can give you sorry I don't know more information about it than that but these settings right here are the ones you want to use so again it will be in the description of the video the whole project will okay so now we have that covered and you kind of know like the wrong way to do it which is you know trying to do it through blueprints essentially and sending over variables let's go into the correct way to do that and before we do that there's some really important concepts I want to go back to this presentation real quick and we're just gonna start off from where we left off and again sorry if you already know this stuff but this stuff is absolutely critical if you are going to be doing any sort of networking code so the first thing I want to cover is this concept of network Authority so for any actor in your game you can check its network Authority or if it has Authority so these are how you would check it on a blueprint side you'd say actor has Authority and return a bool whether or not asketh or T and there's also the switch statement that they have as well just for convenience and on the c++ side there is the has Authority function inside of the actor class so four characters essentially all this means is it's checking if the character is the instance of the character that's on the server so I have a little example here set up so you can see this is just a screenshot from Fortnight and you can see this is the player character over here on the left and then you have some other characters in the game you know like your squadmates right so if this is a server and it would be a listen server right because you're also playing on it if this was a server and you were to call has authority on this actor which is the player it's gonna return true because this character is on the server this is the instance of the character that's on the server and likewise for all the other characters in the level even though they're not the players the server still has authority over all of them because they are the or it is the instance of that character on the server right so this is the server it's going to have authority over all the characters on the server but if this was a client and the server was you know somewhere else or somebody else or maybe it was a dedicated server but if this was a client that was in the level and you said has authority on the player it's gonna return false and likewise it's gonna return false or all the other characters in the level so has Authority is pretty straightforward it's basically just checking hey is this the instance of the character that's on the server and if it is gonna return true otherwise it's going to return false so it's pretty straightforward just it's mostly just checking if it's the server so the next thing is locally control adverse not locally controlled I should probably say locally controlled there's not locally controlled up here in the title but it's that's really what it's checking so just like before there's a really handy blueprint function off of the pawn class and it says is locally controlled and just returns a bool if it is and it's C++ there Z is locally controlled function so I have another example here what locally controlled means is pretty much exactly what it sounds like it's just checking if the instance of the actor that you're calling it on is locally controlled so in this instance if we are the server and we call it on the player it's going to return true because this is the character that we are controlling we are locally controlling this character like if we jump this character will jump if we shoot this character will shoot but if we call it on any of the other characters in the level it's gonna return false because you're not locally controlling these characters if you were to you know you can't make these character jump you can't make them shoot somebody else is controlling these characters so they are what they call remotely controlled right pretty self-explanatory so far but very important to understand and likewise on a client it's not actually any different so if you were to say is locally controlled it's still going to return true because even though you're not the server you're still locally controlling this guy on your client and likewise with all of the other characters in the game on this client if you call it is locally controlled it's also we're gonna return false because you're not locally controlling them so that's also pretty easy to understand the really important one here to understand is the book will roll so just like before you have two different ways of getting it whether you're in blue prancer's Plus and the way this one works is it's essentially an enum and you can see the enum I took a screenshot of it from the engine over here on the right and it can be one of four different values so you could be none simulated proxy autonomous proxy or authority and the order here does matter so you can see none here is essentially like the lowest role that you can have there's no role at all is the description and authority is the highest role you can have so this is this like the server's authority right and the other two I'll explain in the picture a little bit better but the simulated proxy is essentially if you think of it you would have to think of it like you're you know your squadmates in the game like they're not your character they're all the other characters in the game that you're not controlling and autonomous proxy is the controller or sorry is the character that you're controlling but if it's on a server then it's going to have authority so here it'll make more sense once I do a little demonstration here so again so this is a server let's pretend this is a server and we call get local role on this guy the player it's gonna return authority because it is the instance of the character that's on the server and likewise to be call it for any other character on the server it's gonna return an authority so the server is pretty straightforward any character is just gonna return to you authority because it's the instance of the character on the server but if this was a client and you said get local role of this player it would return autonomous proxy because it is the the autonomy that the autonomous proxy is the character that you are controlling locally as long as you're not on a server because if you were on a server it would return authority and if you were to call it for these other guys they would all return simulated proxies as long as you're on a client and what a simulated proxy is like I said before it's any other character in the game that you're not controlling alright so hopefully that makes sense if it doesn't make sense go back and rewatch it you can also Google these terms there's plenty of documentation on them I find it kind of confusing I think a picture works a little bit better but the more our autonomous proxy and simulate approximate just know the autonomous proxy is the one-year control Lane and the simulated proxies are all the other ones you're controlling assuming that you're on a client okay so that is the end of the presentation hopefully you guys are still with me we can now go ahead and jump into the correct way to do it so like I said I didn't want a live code all this and you're about to see why because it's a ton of it's a ton of code and I'm gonna explain it the best that I can do you guys but definitely download it and check it out yourselves I've tried to comment it as best as I can as well so that you guys can kind of read through it on your own okay so let's go back here to our third person character and let's get rid of this old bad way to do it so I'm just gonna unhook these pins and I'm gonna hook up the correct way to do it so a few things to know before we look at the code I did change the parent of this class so we've go to class settings here you can see the parent class is my character and if we look at my character in code it is just a class that's derived from character and the only rule thing that I've added to it was I've added something to the constructor and I've added this get my movement component so let's go ahead and look at both of those so in the constructor I am telling it to use my custom character we have a good opponent I actually have it commented out right now just so I could show you guys the wrong way to do it but I'm gonna go ahead and comment this back and so you can see in the constructor here this is how you tell unreal to use a different character movement component for your character and you can only do this in C++ but it's basically this call right here or we're saying the superest constructor and we're passing in we're calling set default sub object for the connected component and we're sending it to my character movement component which I'll show you guys in a second but that's how we're changing the character movement component to use ours and then the next thing I did was I made this little handy function for getting my movement component just so we didn't have to cast to Mike and movement component every time we wanted to get access to it so all it does is is it just returns the character move a component and it does a little cast for us to my character move component so if we go ahead and recompile this come up here and I use this module windows I've said this in some of our other tutorials but if you don't know what this is you just go windows developer tools and modules and I just have it pinned over here on the left but I use this instead of the compile button because I think it works a lot better you just have to search for your character or you doesn't search for the name of your project and you'll see it pop over here over here on the left and then you hit recompile I found that this button works a lot better than the compile button sometimes the compile button doesn't actually compile your code I don't know exactly why but this seems to work a lot better but all I did was we compile it so if we go back and we look at the third person character movement and we hover over the character movement component you can see it pops up and this is my character maple component and that's because it is now using the character maple comment that I've created and the reason I needed to create this carry Camilla component is because this is how you do replicated movement and unreal or sorry replicated character movement in unreal is by its all done inside of the character movement component so if you want to add to it or change it you have to make a child of the character movement component and use that one instead so the only blueprint code we have our here which is pretty straightforward is again I'm checking the Sprint key just like we were doing down here except this time I'm saying get my movement component which again it's just this little function right here that returns our custom character move the component and we're calling stats printing to true and then we'll release it we're safe at sets printing to false and that's literally all the code we have to do in blueprints in order to get this to work now I need every cent of the code is in C++ and we're going to look out here in a second I'm just thinking if there's anything else I need to cover in this class I don't think there is well okay so let me just run it real quick to show you guys how much better it performs and remember we're still running at this 500 ping so if I go ahead and press play and I'm gonna move the server here on the left and the character over here on the right you can see I can sprint and you'll notice there is none of that crazy or abandon happening anymore even at 500 ping it's super it's super buttery smooth there's still obviously latency between when I perform the action on the client and when I see on the server but that's totally expected there's nothing you can do about that because it simply takes that long for the packets to reach the server so that's totally totally normal and I can also wall run I've added my wall running which I have showed you guys in other tutorials again I'm not doing anything with animations here so he's just doing the running animation when he's on the wall but the all the wall running code is working and it works on the server and the client so you can see my wall run it works on both while we run in both directions and we're not gonna go into like the math behind the wall running code I'll link in the description the wall rain tutorial I have that goes over like all the math and how to do it if you're interested in that but again this is like a networking tutorial not a wall running tutorial but I wanted to show you guys how you would hook up something like while running because it's actually very complex and you have to do in a very specific way so yeah so you can see it works way better now there's no crazy latency or there's no crazy like jittering effects happening and that's because everything is using the character movement component all right so let's go in and look at the character mimic component so you see I have a my character movement component over here and I have everything kind of sectioned off so I want to go through it kind of one at a time all right so this is the character movement component that I have created and you can see it just derives from the normal character moon component and a few things to note before we look at the classic itself I just have everything collapsed right here we have these two other classes down here we have one called saved moved and one called network prediction data for the client so what these are these are used by unreal it's kind of the way that they handle character or network character movement they have a concept of saved moves so whenever you perform a move on the client so let's say you jump for example whenever you jump on the client it performs the jump on the client and then it saves the information about that jump into a saved move this class and then it sends that saved move to the server and so that server could then perform that same move the jump in this case and so the server jumps and then it tells all the other clients to perform that move as well so that's kind of a high overview of how it works but in order to expand upon it we need to create our own safe move class so you can see right here this is my safe move class I created I've over added some functions in here these are just the necessary ones that you need to override and we'll take a look at all these in the C++ file but you can see down here these is the main heart of it this is the main stuff that I've added you can see I have these once to sprint and while run keys down so these are actually what I refer to as compressed Flags so these are just flags which are essentially bully ins that get passed between the client and the server and these are what keep it essentially in sync with one another so if you look up here in the character movement component you can see I have the exact same Flags just minus the saved keyword in front of them so it's so the point of this saved move class is to take these compressed flags for information about the character like he wants to sprint or he's holding on the wall run key and it copies them into this saved move and this gets sent to the server so and then this class down here is essentially just a little helper class that kind of like connects the save move to the character movement component but we won't get into that too much right now so let's just focus on the sprinting right now try to keep things simple so you can see inside the coca movement class I have this set sprinting function and I have this wants to sprint to flag so if we come in here and we look at this set sprinting function all it does is it sets the Sprint key down to whatever value is passed in so this set sprinting function is the same function that we call out here see you're saying set sprinting and we're passing it in true so that then calls this function and sets Franky down to true so this is all happening happening locally on the client right the client I press the shift key or whatever the sprint button is this is all happening locally so somehow we need to get this sprint key down boolean or flag over to the server and that's done using those compressed flags that I was talking about so the way the pressed flags work is there's this set move for and prep move for function so these two functions right here kind of are opposites of one another the set move four takes information from the character movement component like our wants to sprint flag and it copies it into the saved move so you can see it's copying once the sprint into the saved wants to sprint flag and then print me for is just doing the opposite it's copying from the save moved into the character movement component so once it's copied into the save mood unreal is going to call this can combine or sorry it's going to call this get compressed Flags function so if we go ahead and we look at this you can see it's checking if our saved once the sprint is true or set to one and if it is then it's adding the it's adding a custom flag at custom slot 0 onto our result so if you're not familiar with diff Flags this might be a little bit confusing but basically what this is this function is it's a and a unsigned integer 8 which is 8 bits and each bit represents a specific thing so if we go ahead and actually look at these so this is defined inside of unreal you can see they're using the first flag for if the jump keys pressed they're using the second one for if they went to sprint or sorry went to crouch and then they've actually reserved these other two for some reason I'm not sure why it's just as reserved for future use but then they've allowed us to use this remaining four bits for custom things so you can see we have custom flag 0 1 2 3 and I'm using custom flag 0 for sprinting so if we go back here you can see I just made a little comment up here to say ok so custom flag 0 is used for sprinting and I'm also using cousin flag 1 for while running but we'll look at that a little bit later so you can see all it's doing is it's just taking this say it wants to sprint and it's copying it into the compressed flags so once it's inside the compress Flags if we come up here back in the character movement opponent and we look for where is it it's called get compressed flags [Music] or no it's called update from compressed lag sorry yeah update from compress lags so this is doing the opposite it's reading the values from the compressed flags so at this point it sent it over to the server so now this code is actually running on the server so now this wants to sprint key that was set inside of set sprinting up here locally has now been replicated or sent across the network to the server so you can see I'm just doing the exact same thing except I'm where I'm doing the opposite I'm reading from the compress flags so now the server knows that once the sprint is true as well and this is really important because if you if the client starts sprinting the server has to know about it as well otherwise you're gonna be sprinting on the client and not sprinting on the server and the server is not gonna like that cuz it's gonna see that you're much further ahead than you should be so it's gonna be constantly pulling you back which is what happens when you you know do when you start jittering or when you have that rubber-banding and games so when the server thinks you're one place and the client thinks you're another place the server is the ultimate authority so the server is going to say nope you're actually back here and if it's a far distance then you're gonna be teleporting you know constantly over and over which is not good so we need to decide on the server which is what's happening here so now it's set on the server and on the client so now if we look at where that flag is used what I've done here is I've overwritten the get max speed and get max acceleration it functions so if you look at both of these I'm just gonna expand them real quick and it'll come back oops that's not the right one I get an exhilaration and get max speed so these functions all I'm doing here is I've pretty much just copied the parents version of this function but I've added a little bit inside of this case for walking so you can see if we're walking if we're crouching we just returned the crash speed otherwise we return the wants to sprint or sorry we return the sprint speed if we want to sprint which this is our boolean that's getting passed around and sent across the network otherwise we just return the run speed so this sprint speed in this run speed are just variables that I've created inside of my character moving opponent so if we go back we can just look at these real quick so they're inside of the default section here so you can see I have some default variable setup I have a run speed I have a sprint speed I have a run acceleration and it's print acceleration and I had these two other ones for while running which we won't worry about yet but that's all those are these just constant variables better exposed to blueprints so that you can edit them but they're just floats so if I come back here you can see all I'm doing is saying okay if the Sprint key is down then we're trying to sprint sprint speed otherwise just return the run speed or the walk speed whatever you want to call it and the reason this works without any jitter is because again this boolean is getting sent across the network so the server runs this code it's going to say that it's going to see that I want to sprint so it's gonna return the sprint speed and the clients going to run this code it also has this pool set datoria so it's also going to return this sprint speed so the client and the server are synchronized with each other which is why it works good and the acceleration is just the same thing it's just with the Sprint acceleration so we're saying if we want to sprint return the Sprint acceleration otherwise returning the read acceleration so I know it's probably super confusing to you guys which is why I wanted to just give you guys the source code so that you can kind of look at yourself and just kind of briefly explain it like I'm doing right now but this is what you need to do if you want to have Network character movement in your game so you guys asked for it so I made a tutorial so I hope you're happy but this is what you need to do there's no shortcuts around it obviously you need to be you know pretty knowledgeable of C++ to figure this kind of stuff out but hopefully this tutorial will give you a good starting point so the next thing I wanted to talk on is wall running and how I made that networked and that will start to go into those like roles I was talking about a little bit more because sprint teens believe it or not like the simplest thing you can you can really make network but for something like wall running let's go I wanted to go ahead and and show you guys how to do something like that cuz it's actually pretty complex and just kind of give you guys the general idea of how you might tackle something like that so back in the header file let's look at the code associated with the wall running so that's not important so you can see I have these wall writing functions right here so a lot of these functions right here are just math functions like checking if a surface can be wall ran or it's like finding the wall run direction or checking it for next to a wall and I'm not going to go into that stuff because again I'll have a link in the description of this tutorial for like a very mathlete there like I'm and the explanation of how to create wall running like and all the math behind it but again that's not the point is to toriel the points to Torrio's how to hook it up from a networking point of view so let's start from when the character hits the wall because that's really what instantiates a wall run so what i've done basically is in my character move a component if you look at the begin play you can see inside of here i'm saying if the pawn owner which is the owner of this component so just the character basically if the character's local role is greater than simulated proxy so you're probably getting okay what does that mean so again that's why I said the order of these is really important if you go and you look at these it's in it's an Inu and we're saying if the role is greater than simulated proxies so that means if it's autonomous proxy or if it's Authority so we're saying if it's you know a locally controlled character or if it's the character on the server because we don't care about simulated proxies in this case because what we are doing and we're saying okay if this is true then we want to bind to the on actor hit event and we want to bind to this because we want to know when the character hits the wall because when he hits the wall we want to potentially start wall running right but for simulated proxies which again are just like you know other characters on your you know in your instance of your game that you're not controlling you know like enemies or your teammates or whatever those characters like those instances of those characters on your computer are not the ones that should be doing you know collision checks for if they should start wall running those characters their positions are solely updated from the server the server just says okay your position is here your velocities this just move right they're not doing any calculations on your computer so we want to make sure we only do this for locally controlled characters of course characters on the server because characters on the server always need to be doing you know any sort of movement update code so that it stays aligned with what you're doing locally so if that's the case then we're going to bind to the on actor hit event so this on actor hit event is only going to get called for autonomous proxies or or characters with authority on the server so if we go ahead and we look at this on actor hit event so I'm like good fats on actor hit so inside of here we're doing a few checks to determine if we can Rahl run and again all of these checks are happening on the server and on the locally controlled client and that's very important to note because that's that's super important they need to happen on both if they don't have it on both things you're gonna get out of sync so it's checking if the custom movement mode is already set to wall running so this is offending to explain as well so for wall running what I've actually done is I'm using a making use of a custom movement mode and if you're not familiar with movement modes we can go take a look at them real quick so so inside of the engine there's this concept of movement modes and it's just an e new so you've probably seen this before somewhere in your in your code but you know movement modes are things like walking falling swimming flying these are the ones that are built into unreal but they have this option here for custom movement modes and if you specify if you set the movement mode to custom then you have to specify the custom movement mode that you want to use and if we look I have made my own custom movement mode enumeration and the only custom movement mode that I have is walrein but if you had other movement modes in your game like maybe you had one for like skydiving you know like that's 49 or whatever you could add another one here and you know you could have your own custom movement mode forward and handle movement in that way but it's a good thing to create a custom movement mode for something if you're making like a really extreme new movement that isn't handled by any other cases I didn't make one for sprinting just because it was you know sprinting is nothing more than a quicker walk right and there already is one for a walk but for something like wall running or something very specific it's good to create a custom movement mode for this so coming back to where we were before inside of the on actor hit the first thing we're doing is we're basically saying okay are we already wall running and I have made this is custom movement mode function so if we look at this it's just saying is the movement mode custom and if it is it's the custom movement mode equal to what's being passed in so if we're wall running the movement mode is gonna be set to custom because it's a custom type of movement mode that we've created and then we're just chained ok is it equal to this is it equal to custom or is it equal to you while running so that's always saying it's just saying you know are we already wall running and if we are we're returning because there's no reason to try to start wall running again if we're already wall running and then next we just check it for falling because you have to be falling before you can wall run we check if the surface can be wall ran and again these are just functions I wrote you know you can look at them if you want they're just math functions they're covered in my other tutorial which will be in the description and then we find the wall run direction and again all this stuff is happening on the server as well as the client and we make sure that we're actually next to a well and so if everything's good then we call this begin a wall run function so if we look at this get wall run right here this is where we start making use of this compressed flag because if you remember I'm just going to go back to the definition of this real quick or this is our other compressed wire we had one first print and we have this one for wall running so what this flag is is it's gonna be true whenever the shift key is down because the way my game works is that you have to have the shift key down or the sprint key in order to start wall running so if you just jump on the wall and you're not pressing shift you won't actually wall run so I wanted to have this concept okay you have to specify an order to wall run but if you remember all of this code like I said before all this code is running right now on it runs locally on the person who is you know with the mouse and keyboard and then it's running on the server as well so it's not a problem to check input on the local machine because that's super easy right but how do you check if off on the server if the client is pressing the key like you don't have access to their keyboard so this flag has to get sent across the network so we're going to come back to this in a second I want to you guys how this flag is being sent across so if we come back here to the ticket component function well I probably should have covered this earlier when I was talking about the spread stuff but that's okay just ignore this top part for now I'll come back to it later but the right here we're saying well first we're checking if the pawn owner is locate controlled because this this tick function is going to get called on autonomous proxies it's going to get called for simulated proxies and it's gonna get called on the server so we only want to do you know any type of input checking if it's a locally controlled player because otherwise you know it's it's always just gonna return false like if we if we try to check if the F Keys down on the server it's gonna be like no cuz there's literally no keyboard right so we're saying okay if we were the locally controlled instance of this character then I'm saying wall run key down equals our required keys down and essentially this function what it's doing is it's just if we look at it real quick it's just checking if the spring keys down you can take a look at it on your free time but it's just checking if the spring keys down so let me minimize that and come back so it's checking if the spring keys down if it is then it's setting this to true but again this is only happened locally so we need to get this flag over to the server and as you probably guessed that's happening in the exact same way that we got the other flag over to the server and you've already kind of seen this flag being used everywhere but just to kind of reiterate it so once it gets set locally down here and set move four just like the other flag we copy it into the same move and then inside of get compressed flags we copy it from the save moved into the compressed flags and then inside of update compressed Flags its copied out of the compressed flags and set to the servers instance of the wall round keys down so now the server knows and the client knows that the wall run key is down so now back to where we were before which I think we were in begin well round yep so again this begin wall run gets ran on the server and it runs locally so because the spool is being sent across as a compress flag it will be set to true if the ship keys down on the server and on the client which is what we want so when begin warrants get called you can see all doing here is it setting the movement mode and since wall running is a custom movement mode we're saying set moving mode to custom and then we're specifying the custom movement mode to use which is wall running now for movement modes this is something that I had to kind of figure out but the weight movement modes work is if you set a movement mode on the server which we are right here because this code runs on the server and it runs on the locally controlled autonomous proxy if you set it on the server it's going to the engine is going to handle replicating it to all the other clients for you so we don't have to worry about telling all the simulated proxies to also set the movement mode to while running it they're gonna do it automatically which is pretty nice so we're standing on the server so it sends it out to everybody else so now everybody knows including the server that we are while running all right so once the movement mode has been set to custom we're gonna start getting a new function called inside of here so the way that movement modes will work and I'm actually gonna hop over to the character movement component to show you this like not my character movement component but like the engines character movement component this guy here our parent hopefully I can find him yes okay so if we go to the character mode component and again this is like the default one that comes with the character normally this is all engine code but I just want to show you guys how this works so let's see can I search yes so let me find what I'm trying to talk about here school school school school yeah so as you can see inside of the engine code they have these phys functions so it's like phys walking phys now walking phys flying fish swimming physical and if you remember the movement modes from the engine these are actually them there's walking nav walking flying swimming in customs so basically they have a phys for every movement mode in the game and they have one here for custom so basically these fist functions get called each frame to do the to perform the actual movement based on the movement mode so if it's set to flying phase fly-ins gonna get called deceptive walking if this walk is gonna get called it resets a custom which is gonna be when we're wall running this is custom functions going to get called so all I've done in my character movement component is if we look at the overrides among other things I have overridden this is custom function so we go ahead and we look at this so this function is going to get called whenever we whenever the character is wall running and something super super important to note about the fist custom function or any of all of the FISC or all of the physical actions for that matter is that they're only meant to run on the server and on the autonomous locally control of proxy they're not meant to run on simulated properties and that took me a long time to come to that realization so just keep in mind that none of the code inside of your faves functions are going to be running on simulated proxies because simulated proxies you literally like don't have to worry about them at all like the server is just going to handle updating their velocity and updating their position so just maybe that's not important to anybody but it was super important for me to figure that out and I haven't know it up here that pretty much explains that so this is only gonna get Brian on the or it only needs to get ran on the autonomous proxy and the server so the fist cousin function however for some reason and the engine it gets called from another spot and it only happens for the fist custom function I don't really know why I think it could be a bug to be honest but that's why I have this check here that's saying if the local role is simulated procs and you just go ahead and return because like I said we don't want this to run on the simulated proxy I don't think it ever should but anyways inside of here we're doing a switch on the custom movement mode and of course the only one I have right now is the wall running so that's the only case that we have inside of the switch so it's going to be wall running every time for right now but if you had more in here like the sky diving you'd have another case for that and then just like the engine does I have a is wall-running function that I created which is just right here below it so I call that so this whole code is all the magic that happens when your wall running to make the player actually wall run and again super important note I even have it up here at the top this code runs on the server and it runs on the local client and that has to be the case you can't change it otherwise because if you if it's not running on both they will not say synchronized and that's the that's the magic behind it that's what keeps it you know so without how so you don't have any that rubber-banding out I showed you at the beginning but anyways I'm not gonna go too much into the what this function does because it's mostly just math stuff but just you know real quick it it's just making sure that the wall run key is still down because if you like what shift I want you to follow the ball and we make sure that you're still next to a wall and then I calculate the new velocity based off you know which way you should be running and then this safe move updated component I figured out is how you actually update their velocity so you say velocity times Delta time and that's the adjusted value and you pass that to the selection and that's what actually makes him move in the direction so again you can take a look at this code all you want it's not really important for this tutorial but yeah I think there's only one other thing in here that I didn't really cover and it's this on movement mode changed so this this function is kind of useful it's it gets called whenever the movement mode change which of course the movement mode changes whenever we set the movement mode to while running or back from wall running so inside of here I'm calling the Super's movement mode change at the bottom so like that stuff still happens but I have two checks up here I have one for if the movement mode is being set to wall running and then I have another one or if it's being set to something else and it was wall running because there's this previant movement mode so I'm just doing a little you know logic in here and you might need to do stuff in here for your custom movement you know so like for example for the wall running whenever they start while running I stop their movement just to you know make sure they aren't don't have any additional velocity applied and I can strain them to the horizontal axis because when your wall running you you know you can't move up or down we don't want any gravity apply to you so that's just what I use this function point in this case to constrain their constrain their movement I just thought it was a good place to add it and then likewise whenever they stopped while running I unconstrained their movement so that they can fall or go up again right so yeah so I think that is pretty much it hopefully somebody is still watching this video you guys asked me that for this tutorial I did not want to make it cuz I knew it was gonna be a ton of stuff but honestly if you did get this far like this is a lot of good information this took me a long time to figure out how to do this and there's just there's no other way to do it I'd love to make a blueprint toriel on how to do this but it's not possible so if you enjoyed the video please leave a like and subscribe I spent a lot of time getting this working like weeks getting this working so I would really appreciate a thumbs up and subscribe and if you have any questions I'll leave my discord and the description because I'm sure I'll get tons of tons of questions but I'll see you in the next video
Info
Channel: Reids Channel
Views: 9,516
Rating: undefined out of 5
Keywords: Unreal Engine 4, Unreal Engine, Unreal, UE4, Networked Movement, Replicated Movement, Multiplayer, Networking, Replication, Custom Movement, Custom Character Movement Component, Tutorial, How To, Sprinting, Wall Running, Latency, Jitter, Rubber Banding
Id: RtQRMcupJs0
Channel Id: undefined
Length: 52min 48sec (3168 seconds)
Published: Tue Apr 07 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.