Godot 4 multiplayer: Sync 3D player movement, rotation, and animation

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Let's test this guy Run and Jump past him look at [Music] that in my last gdau multiplayer video we had a look at how to spawn players into the world and also synchronize their position but it was very basic so this week I want to have a look at how to be able to move your characters around and be able to look around with the camera and have that position in motion and rotation synced across to the other clients and I also want to look at how to sync the animations like idle jumping walking and running so that the other peers that are connected can see your actions and movements in real time so let's dive in so let's have a look at where we left off last time as you can see our synchronization is very basic but it does work we can't move or turn the camera in any way that's meaningful uh so let's have a look at how to fix that the first thing we're going to do is actually look at the player input script which handles the keyboard and mouse inputs for the player and this file is what the player has authority over so when they're playing the game they don't have authority the client that's actually playing the game doesn't actually have authority over the player object they only have authority over the inputs the keyboard and mouse and maybe I'll touch on that a little later but just keep in mind that the only thing that the actual client is controlling is the inputs to the player so we have some basic variables already set up here for uh synchronization but we need to add a little bit more this do jump will help us uh to get the jump working correctly and we'll see that in a minute we're going to export camera camera base and a lot of this a lot of what you'll see here is based off the demo project that gdau has so if you're C curious to how some of this was set up and you want to look at something more complex I'll put the link to that project in the description all right so now we've got some new objects to represent the camera we need to adjust our camera in the player model a little bit so first I want to do is move the camera mount out from underneath our model we shouldn't really be putting that there so let's just drag this up to the top there and there's our camera mount great and we're going to add a camera rotation object and let's attach a spring arm and the spring arm will help us um make sure we don't run into collisions or buildings it keeps the camera from clipping into the walls and that sort of thing I'm going to set the Collision Mass to two basically it just uh prevents the uh spring arm from colliding into the player and kind of causing this jittery effect by bouncing off maybe a wall and the player's head you know back and forth so that'll kind of prevent that and then let's just bring our camera 3D down in there so that we have our camera mount which is the base of the camera we have our camera rotation which will represent the spin of and rotation of the camera our spring arm and of course our camera which is attached to that spring arm and I like to set the length at about 2.4 and of course we need to come up to our player inputs and now that we're exporting the camera base rotation and Camera 3D we need to drag those over so that we can track those within the script so you can see camera base is mapped to the camera mount camera rotation is mapped to the camera rotation object and then our camera should be mapped to the camera 3D object and it is okay great and you can see that this uh player input object is mapped to that script that I have here so we also need to add a couple more constants to use with the controls for the [Music] camera [Music] uh we're keeping this under 90° because it kind of breaks the camera movement once it hits 90 uh you've probably seen that error a couple times if you played around with camera so we're just going to keep this uh this x rotation clamp to uh 98 uh [Music] 89° and then we'll just move our Max X rotation to 70 and you can play around with that depending on how you'd like to have your maximum camera uh it's just up to you all right so let's make a change here let's remove this set process and we're going to say so if this current Authority is the client that we're on we're going to set that camera as current so if it's not the authority we don't want them coming in here and uh running any of the process functionality for this player input we only want the authority client to be able to call this so that's what this is saying right here uh if if they don't have authority it comes down here and it sets this process uh to not run so it will only be running on the client Authority owner of that of this uh player character and we also turn off any inputs for that as well so we have this input RPC here that will notify all the listeners that the player has jumped and we use that jumping variable down here that is synchronized to let the other clients and the server know that the player has jumped and then we also have a run uh variable here which is synchronized and this is actually kind of a nice highlight between where you want to use a uh sync variable or a synchronization export variable or a RPC so like a jump event is like a single event that happens it's not like a continuous event so you wouldn't really synchronize the change in it so for example this run event can be happening over time right so if I hold shift key and I'm running that's not really a good RPC event because it wasn't like a oneandone type deal it it's it continues to happen so that's why I'm using a synchronizing variable here where is to signify that the player jumped we use this RPC call that also kicks off a status to signify that we jumped now we still use a variable to synchronize to tell our process on the player object that the player is jumping but that's because jumping has some additional logic to it that allows the animation and everything kick off and we'll look at that in a second we also want to handle the input events from the mouse so let's add that [Music] now and we'll create this rotation camera [Music] function oh I spelled camera base wrong whoops so let's go up there and fix that which means we'll probably have to fix this as well so don't forget that yep okay orthon normalize which will clean up our axis uh from any drift and then we'll do camera rotation dot rotate so this will rotate our camera uh and we do negative move X because otherwise it doesn't make sense if you just put if you just make that a positive it will be the opposite of what you expect when you move the mouse uh back and forth uh this is just to clean up our axis so that we don't have any camera or any uh Precision drift in our camera base axis there and then our camera rotation will will be limited or clamped uh based on uh the camera rotation Min and Max that we have over here and this was that camera up down movement that I had added uh to whether or not you want to inverse your mouse movement so if you want to toggle that just set it to a negative one up here and then let's add one more function down [Music] here get camera rotation basis this will allow our player object to have access to this because we're going to do some calculations uh based on this so that they can rotate correctly all right so we just grab the camera rotation object Global transform basis and we'll see that in the next uh in the next class that we edit um I also want to make sure that we're I think our camera set up uh I think it's done there and I just want to make sure that our player input that we're synchronizing down here you you can see that we're actually replicating everything we need to so let's double check there uh so we have our input Direction which we've captured and running which is good and let's also add the camera mount rotation and Camera rotation rotation so we have the camera mount rotation and also the camera camera rotation or camera rot rotation oh one thing I do want to change is uh to update what I was talking about about with this jump RPC we're actually not going to set this we're going to set it to where is it this do jump uh so this is just a flag that we'll use in the player script to initiate the jump object okay let's just clean this up a little bit and drag these up here if I can okay next let's move on to the player script so we got a little bit of work here and this is going to be the bulk of what we do to get this player to move and turn and synchronize those animations all right so let's go ahead and set up all the new variables that we need up here at the top so we've got our speed jump velocity and let's go ahead and think we can remove this camera 3D don't think we need that anymore because we're handling that all in the input file and then this player input we don't need actually we do need that we'll keep that there but let's just rename it to player input oops player input okay first let's add some constants [Music] these constants will help us with the movement in direction that we'll that we'll look at in a [Music] minute motion will basically be our inputs and our root motion and orientation will govern the uh transformations of the player objects so we'll see what those look like in a [Music] second the two animations that we're going to track through this animation enum are just jump up and walk uh we will do idle and uh running but I'm not going to handle it in this enum so this export we will track our current animation so that we can synchronize that to the other peers oh I need to create a new variable here okay or a new object let's create another node 3D and we're going to call this uh player model and I'm going to stick a new model in there right now I'm using the SWAT one I'm going to get rid of that and place the new model in here so let's just we'll get to that in a second and I'm going to add a placeholder animation tree and we'll just drag that over here great and we'll use that animation tree to animate our player we've got the player object and we are setting the multiplayer Authority on that player input object here that you can see so that was this script basically anything in here is authority to the client okay so we have our ready function I'm just going to remove this because we don't need that anymore and we are going to set the animation tree to active that way our animations carry on through all the clients capture our player models Global transformation with orientation and then we'll set its origin to uh default Vector 3 and if it's not a server we do not want it to run the process here so this this process uh physics process uh that we have on this machine uh or on this client will only run on the server and then the rest of the motions and everything will just be synced from the server so we're only going to do that processing on the server our physics process we're going to change up a little bit so I'm just going to remove all this because we're going to make some changes I'm going to have a uh let's do an a multiplayer if multiplayer check this is just going to be our function for handling the players input so that's that's where where we're going to sync the this is where the calculations are going to occur and then if it's not the server then we just animate the player okay so we need to create that apply input function right and the way that this works is this apply function uh only running on the server it's where all the calculations are going to occur like our inputs will be governed by the local client and the server takes those values because they're synchronized we're going to synchronize them I'm going to show you in a second and it performs the movement calculations and it updates Ates the player's rotation and position in velocity and it just synchronizes that through the synchronizing mechanism but locally the peer doesn't need to rerun that because it's governed through the synchronization variables so we just tell the peer to animate the player based on the current uh animation that the player is [Music] [Music] performing okay so our motion is going to capture that player input it's just basically the uh direction that we're going to go and it we interpolate that with the previous motion so it just kind of Smooths it out for us but we're basically wanting to grab this function down [Music] here we're gonna use these uh camera uh X and uh Z and X vectors in a [Music] second we're going to normalize that we just want to keep the magnitude the same so uh we just need to know the direction so that's what we're doing [Music] here and we'll do the same thing with the X Vector on the camera so we're going to apply our gravity if we're not on the floor I think we already had this [Music] before uh and this is where I do my jump little magic using that do jump that variable that's set in the [Music] RPC basically our RPC tells our uh server that this player wants to jump that will come into this condition here and it will set that player to Jumping uh which will in turn uh we'll call this uh animation here uh to kick off the actual jump and we'll just pass for there for now and I really wanted to delay the actual jump motion a little bit because the timing of the animation it it seems like he he's like in the air and then he jumps and it's just because this happens so fast there's no way to do that so I've have seen I believe in their demo project where they do a little bit of delay based on the time that has passed with the Delta I didn't really take care of any of that here I'm just doing something really basic so don't put too much weight into this jump logic so if you want to have something really simp similar you can basically get rid of all this and just probably have a velocity jump call and it'll do something very similar but uh so we're just going to leave it for now and move on so if we're not jumping we're going to be walking if we have movement so let's set our animations to walk and it's not necessarily going to make them walk immediately because I still have to show you how I'm going to set up the animations and uh once we do it'll make a lot more sense but just because it says walk here and he's on the flooor doesn't mean he's going to be walking I I have it set up in a way that uh it's configured based on the blend tree triangle so we'll see that shortly so we're creating this kind of faux Target to represent uh this an object in space based off the camera and our motion changes and I know it's a little tricky but it allows us to perform these rotation calculations around the player so that we can actually enforce the rotation of the player uh based off this rotation so let's just look at how to do that so if we have a Target and we have motion meaning like we've actually uh pushed uh on the keyboard to have them move we'll be able to uh perform these rotation calculations but we want to ignore it if it's uh some trivial value [Music] okay so that'll determine our new basis based off that rotation of that Target like I said it creates that kind of faux object in space and then we get that rotation of our player and then we rotate to that so we kind of do a calculation based on what that rotation would be and then we apply that rotation with this slurp call here that from and and then we provide our Delta with a uh interpolation speed like how fast how smooth and how much weight you want to put on that so you can you can adjust this uh as needed and let's see how to apply that here with our root motion [Music] uh and so we're going to use a uh the animation tree uh root motion functionality to get a transform to apply to our orientation uh basically this allows us to use animations to give us that uh transformation you'll basically want to have an animation like this that actually moves and is not just running in place place and it'll allow you to move the player based on that root motion and if you want to know more about it there's a lot of stuff on the internet about it I'm not the expert at it but I know that this works so we're just going to roll with it so we'll apply that transform to our [Music] orientation so this will provide our uh horizontal velocity [Music] now I'm adding a speed factor to this velocity I'm not sure if this is the best way to do it uh it allows it to allows the player to run a little faster uh there might be a better way to do that so you can play around with that or just not do this at all and get a feel for what that speed looks like and then if you want to make adjustments or if this is wrong let me know and then we can put it in the correct spot I'm just trying to get the multiplayer thing up and running so just be with me let's uh call our move and slide and this will allow our player to move and we'll do some cleanup down [Music] here uh so I guess this is really just a way to clean up our axis and and make sure that everything hasn't accumulated any displacements that are going to be out of whack and I had to look into this a little bit this is from the third person demo that gdau provides and it's really just a way to clean up your orientation and basis uh so that we don't get some drift in the calculations in our axis that we're using to rotate this player don't start to degrade over time okay so now that we have that let's move on to our animate function so we're going to set our current animation to whatever the animation that was passed in and I use this is running to set whether or not the player is running and I'll show you what that looks like in a sec and I'll show you why I I used uh zeros and ones because it's not really a flag it actually in our animation tree or in the animation uh the blend tree that we use for this uh walk or idle also has a run node on it and we when we at one that means it's running and again I'm going to pull that up in a second so these parameters aren't going to show up yet because we haven't added them so I'm just going to add these and then we'll come back and finish them up in a second all right so let's swap out this model I have a new model model that I want to use so I want to go ahead and remove him from the scene let's delete nodes let's just get rid of him and I'm going to stick them in there and I pulled this model off miimo it's a a site by Adobe with a bunch of free animations and characters so let's just have a look at what what that looks like really quick so go ahead and drag this uh this good guy glb up into the model and again you can use any player model this is just something I'm using and I actually want to move out these two out of there and just get rid of this object okay and then we'll drag our animation player over to the animation tree and we're going to have to set the root and this is where we're going to select a new animation node blend tree okay so this is going to be a really basic blend tree I did my best to just get something really quick up and running so let's just see how to do that with the basic animations like jump and walk and that sort of thing so so we're going to create an animation for jump call it jump up set that to jumping and oh by the way uh these animations here idle jumping walking running Etc were pulled in from that model uh that model was what I was showing you earlier uh this blender model here uh has uh four different animations that I'm importing as part of that so when I exported that and dragged it in we get those animations as part of this animation player and you can see here uh we'll go ahead and actually set this up now that I opened it so we have our idle uh set to Loop that way he doesn't just do his Idol animation once and stop same thing with running and walking okay so we got the animations set up there and if we go back to our blend tree uh that's where these come from so for this jump uh this jumping animation uh we want to drag that to a transition and we'll name the transition state so we have a reference to it and I believe if I click on it uh we'll goad ahe and add the two states I'm going to track in here which are walk and jump and we'll drag our walk over to or I'm sorry the jump over to the jump and then let's create a new blend space to D and this will be our walking and we're going to open this editor in a second and it'll all make sense open a time scale call this walk speed drag this to here drag this up to walk and then we could set to walk and then we'll drag our input to there and that's our blend tree yeah it's really simple uh but it does work um so to finish this up though we need to do a couple things I think we've got our uh inputs set on the transition okay so this animation is jumping we've already got that set up and down here this is good and then our blend space uh we're going to hit open editor and what we're going to do is change the scales to this to zero Z and then one okay so one uh one will be our scale here and let's go ahead and add a node we add our idle down here at the bottom so our first animation will be at 0 0 so then we'll do uh another animation over here we'll call this one walking and then the one here will be uh running you can see our nice tree here and this goes back to when I was talking about the Run setting uh we'll add that down here and I I'll show you what that looks like in a minute okay so we've got our idle set see you can see it up here idle set there and let's just make sure that this is walking yep and then we'll set this to running great so we have our animation triangle and if we finish the setup on this animation tree we should start to see things moving up here we go so the animation player has to have a root node uh which is the player model that's the root of the animation so that the animation tree knows where to find the root motion object which is this root here I'll just bring that up again really quick so our Armature is this object here in the player node and it has a skeleton I don't think I can click over there and then it has a root object which is how that root motion thing works you must have that okay so now that we have our animation tree if I hit active maybe we'll get lucky and it'll work right away probably not because sure I missed something if we go over to one of these parameters and I set the blend to one now he's walking so uh just so you have a better idea if you care uh what that is is if I set the blend position to one uh remember back in the the tree here we have this blend space I open the editor uh one is just down here so 01 that's what that means and then if I set it to uh one one which it what's it going to be yep it's going to be running so there's our run animation and it has a little blip in it and because the animation export isn't perfect but your animations will be much better and then if we set it back to uh zero and zero he's just going to idle so he should just be kind of hanging out there moving his arms are a little messed up I think I need to repport the idol but yeah he's subtly moving there very subtle I don't really like that idle animation it's kind of boring but and his arm stance are a little little too tucked in it's like he's got his hands in his pockets um anyway so I can just reexport that idle animation and and have that look nice there all right so it looks like our blend tree set up um let's try to do walking or I'm sorry let's try to do a jump really quick Boop and there's this jump so that all worked out really nice and and you see how quick and easy that was so we have all the basic fundamental animations we've got jump we've got our idle we've got walking and running and it was just I I don't think this blend space was necessarily how you may want to do it in your game I think this works for a really simple I'm not doing any strafing here uh this is just to illustrate that we can synchronize animations pretty easily uh but once you're uh working on your game you will want to revisit and how to set up these blend trees and it gets a little complicated but uh spend some time on it and you'll be able to uh synchronize those animations uh using the similar mechanisms that I have here but again this is just for illustration purposes all right so we got our player animation set up and if we come back into our scripts let's finish setting up our animations down in this area just get that up a little bit more okay so what we can do is to set up okay so what is this for so this is for jumping so we want to go to parameters and we're going to set a transition request and we're going to want to request the jump okay and then we'll do the same thing just copy this down there we do the same thing for Walk we're going to request the walk State and again going back to that walk State that's what this this is mapping to this that state that we're requesting that's walk and jump that's jump and walk that's what exactly what you're seeing that those MA to that and then to do our uh movement for the walk set parameters and we'll do blend position and this not movement but the animation that we want you can actually blend this meaning on that triangle here if you were like here in the middle he would be like somewhere in between a walk and an idle and then the same thing with going up this side here he would be somewhere in between a walk and a run um it's not going to be very clean uh right now in this setup because of the way like I said before this isn't the best animation tree this is just to get it up and running but for your game you can put a little bit more um effort and time into that to make sure that those animations work out really nicely uh so that's all we're trying to do here and we're going to ba base it off the uh motion and then we'll set a flag here on whether or not uh the player is running so so we're basically this is going to be set to like zero or one and this is going to be zero or one as well and again that'll map to that triangle uh if you look at it one more time uh so if it's if we don't have a motion it'll be just down here and then if we do have a motion uh it'll be one for walking and then if you hit whatever the player input running is if that's synced across over that'll set this to one and then you'll be up here which puts us at the running state so we've got our animation set up and we've got our player movement set up I think we're getting pretty close so if we go and let's check the server synchronizer which we had from the last video and what we what we're resynchronizing position player and velocity so we're still going to keep those uh we're not going to sync position anymore so we can trash that uh so we're going to sync a couple different things so we got our player we got our velocity we're going to sync the transform we're going to have to do it manually and then we're going to also sync the motion property right because we're not exploring it we're not going to see it here so we'll do it manually let's do motion and again these are going to sync these are basically sync variables uh between all the clients and peers and then we'll we're going to sync the player model transform I think that's how you do it nice okay and then one more player which is current animation okay great so those will help us with our uh rotation and motion of the player and our model uh Direction and and transform and also our current animation that the player is actually doing so we'll sync those and then we'll make sure we have everything in yeah we have everything synced under the input already I think we verified that and what else I oh one more thing back to the animation I I know this is probably should have done that earlier what we want to do is add a root motion View and again I'm not the expert this is a multiplayer video so this is all like extraneous data uh but what we're going to do is set the animation tree to that and now you can see that it's moving do you see how I did that and you can see like this fake ground U you won't see that in the game this is just temporary just for the setup but uh during the actual gaml it'll it'll work correctly so that's the last thing we wanted to add for our animation and that should get everything working okay great so I think we're almost ready for a test but I just noticed one more thing uh the camera was a little off I just want to bring that back uh to zero let me see if I can okay let's actually set it at 1.6 and we'll also want to make sure that it's rotated correctly and instead of rotating the camera mount itself let's rotate the spring arm and then let's give it a while we're here let's give a slight downward rotation and that should be okay so in theory everything should work uh let's just see what happens let's just start up the game and see what happens okay so of course we had a problem player input input motion invalid index so something doesn't like this input motion let me double check something over in the player input did I forget to create an input motion oh I'm using input direction from the well let's change it the input motion cuz that's the correct one and then of course we have to update input directions okay so input Direction needs to go away that was an oversight and I think I can just hit player I think I can hit player input input Direction input motion there we go so now it's input motion I already have yeah there we go so let's try it again let's hit play let's make sure our guy moves first okay oh s there's this jump and the jump is a little awkward uh because it's like you hit space bar and then he does the jump so it should just be kind of like here uh so I can like cut that short or you can make that adjustment on your jump if however you wanted to make it work for your game but again this isn't an animation tutorial this is a multiplayer tutorial so okay so now I can move around so let's see this will be a lot nicer if I could like capture the mouse but for this we're just going to do this so shouldn't see him run by so so you can see that the the again it's the speed is very high so that's why it kind of looks like he's being silly because I set the speed really high on that velocity calculation but um the animations are working you can see he's walking he's walking he's walking and then if we turn up to run he's running so that looks good there and if I jump look at that synced perfectly I mean it is on the same computer but you get the idea um and then let's test this guy Run and Jump past him look at that okay so now we can do jumps double jumped because it hit the ground and then yeah so there's some things that you can work out like the jump isn't necessarily perfect like I mentioned earlier but it does it demonstrates that you can do a jump and uh it it is synchronized via an RPC and then our running state which is holding shift uh and if you didn't notice that just for Giggles let's just look over over here really quick I do have a input map set up with the shift that aess our run input and of course the ad WS for our movements and that's why that's showing up there and this is excellent so this is working great and I I'm I'm really happy how this turned out it like I said it wasn't too much work to get this up and running and now you have a multiplayer movement complete synchronization with the character movements and it shows the player rotating correctly uh which is really cool before we wrap up let's just highlight some key takeaways from this multiplayer demo the first thing I want to look at is the player input object and under the replication tab you can see that we're synchronizing the running and input motion field and that is heavily used over in this player script to determine the direction of the player based on keyboard input so that the server knows how to calculate the player's rotation and of course at the bottom we also use the running field to determine whether or not the player is running and whether or not we should show that animation and then we also synchronize the camera rotation and the camera mount rotation and when we synchronize those objects it allows the server to figure out which direction the player is facing based off that camera rotation and then it's able to transform and rotate the player and synchronize that to the other clients and then if we have a look under the server synchronizer we're basically synchronizing the most critical fields for the player like velocity trans form in motion and again the server is going to use those fields to synchronize the values to the other client so if the player is moving in some direction it'll know to synchronize those values because we've captured them here and then the last couple fields are current animation and the player model transform so current animation is pretty self-explanatory so whatever the player animation is happening on the client like walking or running we just synchronize that animation to the other peers and then the player model transform is what we use to actually turn the player model so we're not actually turning the Bas player object we're turning the model and that way we have that kind of separation of responsibility there so it may not look like a whole lot but the synchronization of just a few Fields allows us to have that multiplayer functionality which gives us the player rotation and movement we can show jumping we can show running and walking animations and whatever else you want to add to it so you can just use this as a good starting point and build off of that for your multiplayer game anyways if you enjoyed it give it a thumbs up and make sure subscribe because I've got a lot more multiplayer videos in the queue thanks for watching
Info
Channel: Battery Acid Dev
Views: 2,496
Rating: undefined out of 5
Keywords: godot, godotengine, multiplayer game, multiplayer, gamedev, godot 4, godot 4 multiplayer, godot camera rotation
Id: 75t3HrymoBE
Channel Id: undefined
Length: 39min 51sec (2391 seconds)
Published: Thu Nov 09 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.