Large Scale Servers with Unreal Engine 5 || Betide Studio

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome or welcome back to beatride in this video we are going to start the work on the MMO series oh no it's not a series actually it's just a two-part video where in the first one we are going to create our own server architecture to have huge uh Gathering based games or MMO based games or stuff like that where you have a like you have thousands of players joining in a same area and uh like to a single server and stuff like that so this architecture is now is like now will be used for a lot of uh pixel streamed games and where you have huge events and stuff like that so this is a very basic form of that uh server architecture you will have to do a lot of research if you are uh thinking of going into production with this so also we are going to use a web-based language or a web uh backend language that is node.js to code our server now this is not necessary uh websockets would be the main primary use case thing that we are going to use so if you don't uh no node.js and like have control over any other language you just need to write like you just need to know how to write websocket code and you would be sorted you can just see what uh what logic we are writing in node.js and write a similar one in what language you are confident with also node.js would not be the best option uh when you release a game with if you release a game with web sockets so there are much much better options available like for backend I go with node just because it's my uh it's the only web backend language that I know uh much better than others so that's why I prefer using node.js even in my previous videos I have done so so let's see a small preview of what we are going to do today so we will connect to the server from the first screen and the second screen let me open up this so as you we move you can see we are getting replicated and just for your information we are not connected to any Android engine server dedicated server list and server not any type of that but both of them are getting replicated it has basic uh handling of the code like you can move out of the range you can move in the range like if I move out of the range you see the player disappears as soon as they come in it comes out and there are a few different things for optimization done as well everything is replicated there are proxy characters and stuff like that but again this is a pretty basic example because I cannot uh create a complete MMO game in a 1 hour 30 minutes video or something like that whatever the length of the video is I have already edited it and that's why I know it but yeah so let's talk about what we would be doing in part two because in part one we have a few things already you have basic optimization basic web sockets which you can connect to and do uh in part two we would be going and working on voice chat for local players so you can talk to the like to to the people around you and stuff you can connect to play Fab now this is a question for you I haven't recorded the second part so you can go to the community Tab and select if you want to connect this MMO game that you are creating with an MMO server or with playfab servers uh sorry playfab what do we say play Fab login system account system and stuff or you want a custom made dashboard system whatever you select we would be making that and then we would also be working on a small things like we would be working on small things like you have dresses which would get replicated you would have a chat system would which would get dedicated uh sorry replicated and stuff like that but the basic building block would be laid here and the server basic server handling would be completed in this video itself that's it let's move on to the next topic please do remember to check out the community Tab and just select the option so that we have we are sure that uh you prefer cliffhab or more or a custom built solution for a MMO game more and we would be doing it and then also we would be duplicating Ai and stuffs like that in the next video also so let's get this video started hope you like it uh if you do please hit the Subscribe button and like button I don't know just thanks thanks a lot bye so welcome back to the screen so now we have to create the folder structure for our complete project so let's right click and create a new folder for servers s e r v e r s servers and set name so now we also need a new folder for uh Unreal Engine project so let's create that also on real project save so uh these are the only two folders required as of now now you will also need node.js to be installed into your PC you can just download this 18.17.1 like recommended for most users version and that would be enough um for this video so also just remember that that should be added to path now let's create a new file here uh yeah file oh before that let's write CMD uh open up this uh path in command command prompt so let's open up CMD and write code or npm in ID so this will initialize an uh node.js project for us so just press enter enter enter enter it says yes is this okay just press enter and it would take it yes and we have now a platform package.json getting added now create a new file name this index dot JS because that is the default file that would run if you want so index.js is the default one and now let's open up this folder in Visual Studio code so for that you can open up the path in the command and write code dot you can open up visual studio code directly also that is not a problem or that is not something to worry about so let's open up the index dot index.js file and then let's go to the terminal because we need to install a few modules so let's write npm installed WS so this will install the websocket modules which we will be using uh for our complete project so now we can just write import websocket server and it will like sorry I pressed enter I wrote the complete line but yeah it basically just Imports a a websocket server variable from WS so the websocket server is a variable name so which you can modify according to your project needs and if you want to modify it it's just a variable then let's add const const WSS is equal to new websocket server the variable we made up above websocket server in bracket port curly bracesport 8080 I am going to use port 8080 if you want you can use any other code but yeah that Port should be free if you want to use it or it will give an error next we need to make player data variable so let's add const players data and it would be an empty array so this is going to be a array of all the players and their details um at this point this needs to be empty so this is just a variable declaration and it's empty let's let to be empty now we will make WSS dot on and this would fire any event whenever we receive a connection and we can name a function brackets oh sorry function connection brackets WS and then in curly braces we will write WS now we will from the Ws variable we made above we will receive if the player sends any message sorry for that message sorry that was all that's all that sound but yeah and we will declare a function for this message now we can just Define the data so this database is what we are going to use for like decrypting it and checking if it's a Json and stuff like that or the bracket theme I did not need to add the packet here so don't add the closing brackets here just add it afterwards bracket for this is complete bracket for this needs to be complete here it's now complete so uh after this let's move on we will get const player uh sorry parsed data so we are going to basically break the data that we received into a Json format so json.parse brackets data and then after we have the data in our Json format we will check if it is a valid data or not pass Theta dot Json uh yeah we can directly check the type so and we will check if the type is equal to player data so this type has to be sent from Unreal Engine and we will be seeing how we do that but yeah now we will write console const player ID so these are the details that we would be receiving from Unreal Engine so player ID position of the player and then velocity of the player rotation of the player and also what is the current health of the player so that is it that is what currently we are going to replicate but in future uh like in the second part of the series we would be replicating a lot of different things so now we will this we will set it equal to past data dot data and these spellings should match uh the data type that you are going to declare and then we will get the players data and with this in this array we are going to insert it with that player ID so that anytime we can get and set the values using that layer ID Now set this equal to position sorry double so we can remove double s it's single it should be single yeah velocity we also need rotation the variables that we captured from the past data.data variable health and yeah that is it one more thing uh now we will need to create another function to like send this info to all other clients that are connected to us at this point so for that we can create a new function here and name this broadcast information and brackets and let's add the calibrases yeah so uh a few things that we need to replicate are what you already know player ID position velocity what is the rotation and health please note that we are going to modify this uh script to make it much better and uh as we move ahead so this whatever we are writing now currently is not final so let's add const data to be updated is equal to semicolon oh sorry like braces and set the type to be all player data and let's add a comma data object Dot entry so we are going to take all the entries from the player data variable that we have player data dot map bracket bracket semicolon player ID so basically what we are going to do is we are going to divide them depending upon the player ID and make a Json for that and return them to the users so that's why uh we have this player ID thing and now we also need to add the player data variable and then our DOT variables so set this to player ID comma three dots player data so all the variables would go into player ID and player data separately so we don't have any other issues uh I don't know why we have maybe I've did something wrong oh okay sorry I used the wrong uh type of braces here it should be yeah this one and we will remove the extra uh this thing and add curly basis now it's better so uh that's it let's move on to the next thing so after correcting the above structure we will now make a string that is const data to send string which we will like stringify the above data to be updated string so that we can send it in form of uh uh string in place of data like in place of Json and then we will Loop through all the clients that are connected to This websocket Server by wss.clients and for each and just send them this is string that that we got um uh like we got from above now what we need to do is we just need to call the broadcast information function below here now we are completely done with the code for the basic starter pack we will change a hell lot of things in this code after we are done so don't worry don't think that this is not an optimized thing etc etc we are going to like make it a lot more optimized till the end of this video so now you see we get an error that we cannot load the module so go to play uh package.json and here add a new entry for type and name this module now go back to index.js and just play it and you will see it is saying running uh and yeah it's working properly now so let's move on to the next thing that is creating our own Unreal Engine project so let's open up uh Unreal Engine and let's create a new project I have already selected the project path and we will be using top down character so we can see everything very clearly and most MMORPG games are top down usually you can select any this doesn't reflect how things are going to be uh because uh we are going to have everything in the game system so even if you select third person it would not be a problem so let's select the project name which would be MMO video or anything like that MMO project looks much nicer yeah and this is a blueprint project we do not need any C plus plus in this project we will need an empty C plus plus class uh that is just for adding some plugins but other than that nothing else is required now the first thing that we are going to do is enable varist plugin so for that what you can do is let's go to the project go to the plugins before that let's install the websocket Neo we are going to use this plugin for our websocket implementation in our game uh you can do this in C plus or buy some plugin from the my Android engine Marketplace also but because we have already made a open source plugin for that so you can use that also so which we are going to use for the complete video itself so we will add a MTC plus class in the project because that is required to add this plugin to the project itself so okay you know let's close the project go to your drive YouTube let's create a new plugin folder so name this plugins and then just paste the plugin here I will have to copy it one sec yeah so we will copy websocket new from here and paste it here and go back right click uh generate Visual Studio files and then just uh double click and open up the project it will ask you to rebuild if you are on any Unreal Engine version so just say Yes uh you can use this with any Unreal Engine version so that is not a problem so after the project is open the only last thing that we need to do is we need to go to the plugin section back and just to verify if the websocket Neo is enabled and we now need to enable varrest as promised so let's enable this and restart the project again and then we now have all the things required for this thing to be running in like from Pro plugins point of view so now let's create a new folder named MMO content which I just created and add a new folder in it for blueprints we are going to create all the basic stuff here firstly like interfaces now we are not going to use any type of casting as I promise in the starting of the video we are going to use interfaces to communicate between the classes to keep it a bit on unreal's structure on how unjust uh like should be used correctly so let's create two interfaces so the first one would be for the character and the second one would be for the game instance so the first one is BPI character and the second one needs to be BPI game instance now you can also keep it referenced BPI here means blueprint interface if you want you can even name this BPI Dash game name Dash character if you want to keep it specific for your own uh character or stuff like that so let's open up BPI BPI game instance and rename the first function to connect to MMO server let's make MMO small because like uh just like it has better capital and naming things and let's add an input variable which would be the player ID so this player ID we would be asking a user to enter or will generate our own self So currently it would be random but if you have a login system where you get the username from the user you can use that but that yeah but remember that username should be unique so let's create a new folder for game and right click here and create a new blueprint class you can right click and go to create a blueprint class from here or you can create it from here now go to all classes and search for game instance so game instance is the only class that is uh uh present throughout the game like even even uh when you change levels this class would not be destroyed it would be present for the complete timeline of the game so name this BB game instance and open this up and the second thing that you need to do is go to class uh class defaults uh sorry class settings and then add no sorry add the interface that to implement the interface that we created which is BPI game instance and now we got the function on the left side connect to MMO server so we will implement the event and continue from here so let's get the websocket subsystem from here and just check if it is valid or not so you can add is valid node and then we will bind the event to a response for connected so whenever a websocket connection is established it will like fire this event or even if we try to connect init Fields then also this event would be fired so we do not need to use the response as of now you can show this in the UI hey websocket server was connected or stuff like that but it's not required as of now so then we would go to assign event on message so whenever message is received from the websocket server this would fire and this is going to be a lot like we are going to take it in a lot of uses so after this what we need to do next is to connect to the websocket server itself which has a WS websocket URL of something which I will show now so let's call connect to websocket and here we need to ask the websocket URL so uh the websocket URL usually starts with WS or WSS so uh now before we put the Ws or WSS I just want to say normally websockets will have a URL of WS because we don't have an SSL or any certificate installed for security reasons and it would be on port 8080 so we would be using WS but if you have a certificate installed and you can make secure connections you can use WSS so we are going to do WS then that marks and localhost 8080 so localhost if you are using a hosted somewhere you can put the URL like IP of that remember inbound and outbound traffic on the port should be open so that uh to and fro communication can happen uh using that now we are using localhost because we will be locally testing everything out and in the second part video we will be hosting it on a virtual machine so don't worry for that so after the connection is made we are going to open a level and this level is going to be our third person level which is in here so I cannot right click okay uh oh sorry this level is already open so let's go back to top down map press new level and open up anyone so we can use empty level now right click rename and copy the name for it and paste it here so after the paste is done uh we will now he want to debug the values which we get as a response here so before that either we can test uh the connection logic also if you want that yeah the websockets are working as intended or they are not crashing on connection so for that we will create a new folder for levels and we will then add a new level so let's go new level and we will use this one and remove the block because that is not needed we will add a widget here for the menu so go to top down save the level here and name this anything main menu map or something like that so this main menu map is the one that you're going to join so let's go back to Blueprints and create a new folder for widgets so let's create a new widget which is uh maybe for the main menu main wbp main menu widget or my new widget add a canvas panel and this will have a background image uh so that it BL like it mixes up nicely and doesn't look bad like we are a bit professional right we don't make it look bad so add a background image add a image give it a color let's make it cover the whole screen and then select the opacity to V5 and then the color to be black and a value to be maybe 0.3 something and Save now what we need to do is we need to add a button here and a text so let's add a text here firstly we can name this something game name or video or whatever you want to put nothing like uh whatever your nicely wishes and I will like give it a huge font and robot anything you can skip this and go ahead so let's add a button here uh Center it out and I will skip the button design part if you want you can check it and stop in between and see how it's done so the button is ready now let's uh add an event for it I will delete these extra events from here and let's get the game instance or not this one get game instance and then we will call connect to websocket sorry connect to a memo server I'm really sorry and in the player ID what we are going to pass is some random IDs now if you want you can take input from the player at this point also but we are going to randomly generate it um like we will have some append thing let's search for append now we need to search for random integer in range and then we have to set a max value of three you can name it anything four thousand ten thousand whatever you want the player tag it to be and then we will call the append and in the first one we will write player and in the B1 we will pass in the random integer so every time we press connect it would pass up a random uh random username it would be player random integer then so player one player thousand player to 200 something like that so let's back go back to the game instance and continue our work on what all is left and a lot of things are left at this point so let's get started with that so let's create a new function and this function can be name get player in snap so this will return like update all the players that are in the map basically so this will take an input which would be the Json received uh from websocket server so it should be a string and then we will get the virus subsystem and break this string into a Json so we will convert it back to a Json so decode Json object and we will pass in the Json string and we will receive it as a straight as a what do we say as a Json which has all the values in it next what you need to do after we see we will check if this is valid or not so that even if it is not valid the game doesn't crash and if it is valid then although in blueprints it won't crash but anyways if it is valid then we will get a field get a string field and we will check if the field type uh sorry the field name type is equal to player data or not equal exactly all player data uh here is the type that we are passing so it should be exactly equal to this so copy the name from there and then add a branch so if both of them are equal then we want to update all the proxy characters in the map so from here what we can do is we can get a array field so we are receiving all the player data as an array so here we are receiving all the player data as an array as you can see this so we will get receive this data and make a for each Loop and then we can get values from this array element so it would be better because we are going to change the structures a little bit later it would be better that we create a function here but what we can do is for now let's do it here and later we can convert it to a function so we see this as an object and then here uh this written value we will receive Fields so get string field so uh this thing would have let's go back player ID and uh you will have to do one thing yeah we need to save this player ID in the game instance somewhere so let's name this current player ID so that uh we can check if this player ID is equal to our current one so let's go back to get place in map and now from this object we will take out a few things like position rotation velocity Etc so let's take out the first variable to be positioned we can even copy it from Visual Studio code if you want if the spellings should match exactly as you gave it in the uh code so the second is rotation and the last one is do we need velocity at this point so I think we can yeah we can delete it for now so we will come back to it later we will have to add velocity anyhow but yeah for now let's leave it so add a branch and then check the player ID if it is equal case insensitive to the current player ID if it is equal then we don't want to do anything not Boolean so if this is true and like we inverse it so this true will be fired when uh this player ID and the player ID key coming from the object are not equal now on this true thing we need to create a proxy player so we don't have any proxy players blueprint so proxy player means like in reality there is no character uh replicated getting here so what we need to do is we want to spawn a top down player for each player ID and uh set it position and location and all the details so let's open up the top down menu map and sorry top-down map and go to the location where the default character class is located so this is the default character class so we will right click this and create child blueprint class name this BP top down oh sorry BB proxy character and open this up so in this BP proxy character what we are going to do is we are going to class settings uh we can go to the child closets oh sorry parent class itself so in PP top down character in the parent class add BPI character yeah compile and save go back to your proxy character and you will notice uh the uh we have inherited that interface itself so now to create a function for this we have we will have to go back oh and now I closed all the extra tabs and let's open a BPI character and here we will have to add two functions the first one is is proxy character which will have an output of a result so if this is a proxy character it would return true and if it is a controlled character it would return false so turn this to true for BP proxy character and create a new function in the VPI character which is uh which will return our assigned clear ID so let's write get allotted pair ID and player ID will only be assigned to uh proxy characters because it is not needed for it is not needed for uh controlled characters as in the game instance we have it already so before adding new functions let's go back to the proxy character and right click Implement function and now let's make this player ID a variable you can take it from here or right click promote to a variable and this player ID variable should be exposed on spawn and also uh instance editable so that when when we spawn this uh using blueprints we can set the player ID on a spawn uh we will I will show you what I mean by that in a few minutes but let's go to BPI if character back and add a new function for set property actor transform and the only input that we require as of now is the transform and let's select to be a string oh sorry transform type compile and save and go back to BPI and right click this and you will see uh we implemented the function so promote the transform to a variable so uh so basically whenever we call this set proxy after transform we will get we will be getting this transform variable set on now intake we will send the actor location uh yeah so we will get T interrupt 2 so now what we are going to do is we will have a smooth transition to uh location and transformation we don't have set actually transform right no set let's right click and break up the location and set the location and for the current location we will get the current location of this process proxy character and Target would be the transform that we got set which one which is this uh we can name this Target Transformer something like that yeah and set this to the Target oops oh yeah sometime unreal just listen to want to do something yeah and set the Delta time and interrupt uh speed needs to be something five six ten whatever you feel is smoother for game it's not uh uh defined value Now set the actor rotation also and you can pass the rotation here so every time you we don't need the scale as of now but you have some game where you want to pass the scale or stuff like that you can do that so this will smoothly blend the current location and move the proxy character to the Target location like very very smoothly so you won't feel uh that it is getting replicated at a breaks of 0.1 second so now uh on Branch we will add a for each loop with break so we will find through all the proxy characters that if we have any proxy character or not so get all address of class and search for character uh see we don't need the direct reference as of now because we are using Game Windows where we are using interfaces so get the allotted ID now this ID will not be allotted for the top down player it will only be allotted for the proxy character so we will verify if the player IDs of that proxy character is equal to the player ID that we got from that all player data and if it is equal to then we will firstly break like this yeah and we will need a Boolean also over it uh but how would we so let's do one thing select all the code after this as object node and collapse it to a function name this function update proxy character or something like that so I would name update proxy players and go here oh and change this thing to player Json response here reference whatever you want and now here let's create a local variable and check if the layer was found if the player was found we will set this Boolean to true now if ever this Boolean is getting set to true that means uh the proxy player is present on that map so uh the second thing that we need to do is we need to update one sec yeah we need to uh set proxy actor transform so we need to accept the Arctic transform to an updated location so set this thing up and we need to set location rotation and scale so we are already getting that those values from that uh Json which has the location and rotation and all the X and Y and Z values that we sent to it so let's work on it now so we will get the Stringfield field from position uh we can name the field X so the field that we are going to get is x y and z so x y and z and then we will make a float make literal float I think right I can plug any one and try to make little 40 yeah and I can remove this save delete oh sorry it should be make Vector yeah now pass the X uh y and z and this will return us a written as a vector now one more thing that we can do is to simplify everything is to convert it into a separate function in itself but we can do it later so now just plug the location uh like this little Vector into the location thing and copy this complete thing where we do the conversion and get the X and Y and Z value because for rotation also we need to get the X Y and Z value so now we will search for make rotator and plug in the XYZ values in the same order and this rotation would be plugged back into the rotator so now we are setting up the location and rotation for the already existing things but we are not spawning the proxy characters as of now so it would be always empty so we will check if the player was found using the local variable if it was not found then the false statement would be fired so on false we will spawn acted from class which would be the proxy character and here we will respond then we will get the uh we will make transform and set the values to be X and Y so the play response at the place where we get the data from so X and Y and for the player ID we will get the player ID from above uh this one and we can make it a bit beautiful I don't know if this makes the code beautiful or not but yeah at least we can make it little bit organized and let's compile and save so this will spawn the proxy character whenever we receive input for which the character is not always present into the map and because we are checking the player ID equal to our own so it will not it will not despawn a proxy character for our own mesh so we have done pretty much work and now we can we have a good ground to just uh update the position and the location of The Players themselves even graph what we we like have this function right we need to where we get the response we need to call the get players in map and pass in the response so that we can uh check the values and stuff like that so uh this is the only small thing we I think we were left with and now we can like uh code we can firstly add a comment here so that we don't get messed up at some later point now let's go to the BP top down character and uh in the event graph let's type even begin play and on begin play what we need to do is everything 0.1 second update the server on our own position so set timer by event and here's 0.1 second and right click uh promote to a variable and just name this timer handle something yeah eminent so uh now this event can we make a custom event and this should be looping because every 0.1 second we need to update the websocket server about our location velocity and all the different stuffs that we are going to have so let's call branch and we will verify if the equal to so we will need to see what was the last updated location so for instance is our location did not change since the last update then we do not need to update the server about that position so promote it to a variable and name this largest uh dated location and if both are same then we do not need to set the value uh this should go into false right here this should go in false and if those are not same we will set the last updated location to the current one and send the server an update for it we don't have an event for sending right uh let's go to game instance BPI game instance and create a new function for it update here transform and let's set the input to take the transform from us now we are also passing velocity and that is due to a reason uh for NM graph we will need a velocity to play the animations and that's why we are passing the velocity you can use it for different purposes also but for now we are just passing it for animation purposes so now we will update the player transform uh this is the last updated transform is the local transform and the velocity would be velocity length and then here we a vector length and here we will get the velocity so this will pass the velocity for that let's come in this thing so now let's go back to the game instance because this part is completely done from the top down character we will have to come back for future changes but now we can go back to the game instance and here we will see this new function set player transform right update Play transform so Implement that function and now what we can do is we can like start working on this one so let's get the what is subsystem because uh we will have to make a Json to like send to the websocket servers and then change it into string so construct Json object and you can take this as a variable also and if you want you can do directly also but I usually prefer to take it a variable at some points you will see I don't take it available and I just pass it directly but yeah if you want it's like completely your preference so set string field and then you need to set the type now this type should be exactly the same that we put on the website so uh we will get the clear data and paste it here next what you need to do is uh we need to again construct an Json object and that is for the player data that we are going to pass promoted to a variable name this player data object so this way we can like characterize all the variables that we are going to create for play like update variables so set a string field and let's go back to visual studio and the first is the player ID itself so the first variable that we are going to pass is the player ID which is which we can get from the current player ID next variable that we need to pass is the position so for that we will again need a Json object uh although we do not need a variable for it directly uh but let's create it later we can delete it player location or position object yeah uh I will I we will make it better in a few minutes so set string field we need to set the string field for x y and z let's do one thing let's convert it into a function right click create function uh name this convert Json to XYZ or maybe sorry xyz2 Json sorry and open this up so we will T we will remove this and we will just uh construct a new Json object itself and directly plug it into the target and one more thing that we need to do is we need to take X Y and Z input so X I.E and z and after this is done we will return the constructed Json object so that even if because for rotation and location the x y z values are going to be the in the same format so let's name this yeah it's correct let's go back and here you would see now we have an XYZ function for location and rotation uh so let's get the transform and break the location and pass the XYZ now same thing we have to do for rotation so let's copy the XYZ to Json back here because it's a function of course so now we will pass the rotation break rotator and pass the XYZ looks nice so uh this way we are now passing the location and rotation and now we can pass it back to the constructed Json that we created before that is a player data Json so oh before that we need to do one more thing and we need to finish that also so set a string field oh sorry set object field and let's go back this should be the position variable and pass the position or where is it the first one is the position right here and then we also need to pass in the rotation uh copy the spelling rotation and pass it to this so now one more thing that you need to pass is the string field or is the velocity variable so we can get the velocity directly from here I just want the code to look a little bit better and that's why I set a bit of time on this but anyways so the velocity is now getting passed and now we can close all the variables and uh pass the things back to websocket and call the URL so uh for that we just need to set the objects in the Json format that we wanted to make so copy in just a second yeah let's get the player transformation object and then set object field and here we will pass data and we will pass the player data object here and also we can remove that position because that is now normal required and from here we will set uh encode Json to a single string and we will call our websocket subsystem get websocket subsystem and we will call uh set web send websocket message so uh now this is the only part required for say are we sending the updating update player transform functions so that is also now covered out also just to remind you we will make it a lot better as we move on in the series so have faith on it so now let's go back and here we will take a here we are taking location and everything right position we now need to take velocity also or we need a string so let's bring here and pass in velocity and this velocity would be passed on to this update player transformation object so let's go to set player proxy transform and give it a new variable also for velocity and Float so velocity is a fluid type so that's why and here in the game instance drag the velocity and paste it out in the velocity thing so now the velocity would be passed on so we can edit our uh game and edit our animation graph to have the Velocity shown so right click this and name this velocity current velocity yeah and one more minor thing oh why is it a what happened I restarted the engine and it started working so let's go to the game uh sorry any instance and here we will take the reference of the proxy character so for that what we can do is uh we can go back to add a new function and name this or no uh let's not add the new one delete this go to get linear add info so in the variable where we get the player info we will also add a variable to get the o naught and input sorry an output we will also add an input we will also add a way to get the velocity so set this to Velocity and go back to game since uh let's delete this function go to interfaces and double this now it says so pass in the player ID and also pass in the velocity compile and Save let's go back to our NM instance and here we can uh what we can do is here where we set this speed right we need to verify if this is speed is equal to like if this is speed is set for the owning player or is it a proxy player so if it is a proxy player we need to use the velocity that we pass from websocket so here we will make it down add a branch here if this is uh if this Pro if this is not a proxy player then we will use the old method of getting the velocity if this is a proxy player what we can do is we will get from here get uh yeah and then we will pass in the velocity from here that we get from the websocket get allotted player ID and info uh one more thing we can disconnect this should move variable for now uh later we will connect it back but for now we do not want to have checks because we are not getting the acceleration from the proxy player so we can just verify the ground speed is greater than that and we will just move the player so save all so technically we have the complete setup done uh everything should work smoothly hopefully smoothly everything so let's go back to our uh widgets main menu widgets sorry and uh select the game mode as a default one and open the game and on event begin play we will create a widget before that we can get the player controller and set the input mode to UI only yeah now let's create widget this widget should be menu widget and add it to viewport and connect it uh one more thing that we need to do is set show mouse cursor to true and compile and save let's go and test this thing out do you think everything would work properly Let's uh let's set the input mode back to game uh I think because I'm really honest for top with top down I haven't uh set the input mode and stuff like that before so I'm pretty sure they would be using UI but for now let's set it to game only and uh just that we know yeah we connected and things like that and later we can remove it and set it back to how it was before so game only and connected here now we let's make one more widget uh for our in-game UI so that we can see what is our username which it's user interface uh okay widget and let's go here canvas panel text set this to uh size content uh and send this to the top right corner and give a bit of patching I don't think you need to see how the UI is made I would skip this part a fast forwarded but looks like we don't have to do much more stuff here so nothing would help us fast forwarding so let's create uh or maybe bind it to a function and this would basically take the name of the player or the player ID that is generated by that is generated when we start the game so player ID and we will make a x variable get game instance oh yeah let's create a new function for this and get player ID and this we can add a compact node title and this would output a few things uh first is the player ID that we are making of course and this would be of type string so compile and Save and go back to the widget and from here uh let's call get player ID Oh I thought that compact node would not have a pure would be a pair function but looks like it isn't oh let's add a variable for this player ID you can add a curly brace X curly brace and it would add a variable down there with that variable name being in the center of the curly braces now let's go to interfaces and implement this one let's just copy this current ID and paste it here save all and go back to the main menu and let's give it a try as you can see we are using uh two players but on a standalone mode so this is not connected to any server or something like that uh technically uh we also need to start this over so let's start this running uh server.t sorry index.js now let's go back and connect to the server connect to server oops it should have opened up uh no it did not something goes wrong oh so we forgot to set the game instance so go to maps and modes and set the game instance that you are using to BP game instance and now when you press on connect to server you should be in the server so as you can see we are able to move and everything that you are able to do although you are sending the location you don't know because uh there is something missing which we will fix now so you can see how you you like both of them connected to the server correctly but uh like both the players cannot see each other so this is a minor thing that we have to fix uh the minor the major reason is uh the event begin play is not firing for the proxy character so let's go and fix that thing now so just search for proxy character and open that up and go to event graph and you will find this node uh which says event pick and play do you know why uh the logic is not working because we were not setting up the actor transform and because the event we can play was not calling anything it was calling the parent functions and if you remember on the parent function what do we do on the parent function we update the set a timer to update the location of the character so let me just show and it was calling this complete function so that's why the proxy character was sending its own location to the servers which was not required now yes that's correct we should have added a check but it's not needed because the proxy character is our child blueprint which has now its own event begin play until you just want something uh from the top down character till then you are safe you do not need to add a check so we added a so we added a few print strings while I was debugging it why it was not working and you can see things look pretty nice uh if you're thinking why the game is lagging a bit it's because I was experimenting and I added a hell or document strings and also something is running in my background which is taking up a lot of memory uh which I cannot tell so things look nice till now so let's move on I can remove these print strings because these are no more required uh yeah and if I connect connect we have our old character tick tick and it looks pretty good like the game looks smooth uh now yeah and even if I move slowly it's you can see everything is getting replicated the animations and stuff like that so it doesn't seem like we are having issues now so we can like probably move on to the next step do you know we created a widget which is not getting added to the screen if you have seen properly so let's go to the top down character and even even begin play after we add this thing on the timer we will just create a widget and add it to screen so now when we connect to server you will notice uh oh we forgot to bind it I'm really sorry yeah let's go and play sorry yeah connect to server I restarted the server so you can see player id19036 and player ID one two three four three nice random numbers are like really nice random numbers so this looks pretty good um like now you can like add any type of login methods and pass this username that you want so if you want to like have a dynamic system or something like that we would be covering that in part two of the video so it won't study for that let's move on to the next topic so now when everything is done let's move on to some Advanced topics and start working on them so the first thing is uh for optimization the most important thing is how you scale the players like for instance if the players are within thousand meters of range then you want them to be shown to each other but if the second player moves out of the range you don't want the players to be able to see each other because from optimization point of view that's not required and like if in a MMO game you show all the Thousand players it would be all the thousand plus players it would be a miss so let's go and fix this thing up so the first thing that we need to do is we have this WS client so we need to save this with the player data so we can uh sorry we can we have to save this with the player data so that we can know that hey this actor is uh calling like this actor has this what do we say this WSS WS client so just add WS in front of this and also here in the broadcast information add WS player ID so this would call this function with this ws and player ID so we will have to add uh two functions here name this current client and current player ID so now we have the Ws client and the player ID here so after this is done we would make we would make a data object but not fill the data we would uh maybe we can just cut this up and paste it here we will just be creating an empty uh array which would we would update so now we are going through and for each Loop so we will get const player ID which player ID is right here player ID and then we also need the player data of object dot entries and then we get the player ID oh sorry we will get the clear data sorry so we are going through a loop of all the details player players data why here we have two variables we only have we only should have one right have we used one okay AI at this one this one is also used right and that's why it's showing back to back okay no worries we will name this player data so after uh this Loop starts we will just add a this thing and we will check if uh if the player ID is equal to the current player ID then we don't want to upgrade it also we check this already in the engine also but then also we will check here and we will calculate a distance between them now for calculating distance we need another function so we should go here and add a new function for it function calculate distance between position one position two we can make const X is equal to position 1 Dot x minus position 2 Dot y oh sorry 4 dot X sorry and just copy this so in the first one we have X the second one we have y in the third one we have said and same way here yeah so we calculate this and then we return the math dot sqrt because this can be negative so we need to do this X into oh sorry X into X Plus Y into y Plus set into set and then so we would get the distance between them back so here we should go back and then we will calculate the distance between these two positions the current layer ID's position and the positions of the player data that we got so we will get the player data Dot position and the second variable should be players data parent layer ID dot position and done so after we calculate the distance and we we can now just make a if check statement or like that if it is less than 1000 later according to our needs we can change this I don't know how much thousand is going to be as of now sorry for that but yeah uh I don't know then we add data to be updated dot data dot push and we push the player ID uh why did I add this this is the correct one yeah we will push the player ID then three dots and then the player data do not use and yeah it's correct okay let's end this and now we just stringify this data to be updated after the loop is finished and then for each client uh we can send it back so now after we have done like we have seen that most of the stuffs are working let's move on to the next step and make this project more modular in terms of more modular what I want to say is currently we are broadcasting the info for all the clients to all the clients whenever something gets updated which is not a good way to do things we want to be like optimized and only broadcast info for those players who update their own position and also if they are in the range of the other players so we need to solve this thing so what we are going to do is now we are going below this function okay let's make another function firstly we will name this function calculate distance and we are going to take two distances between players position one position two now currently we only have a 2d position X and Y uh sorry X Min Z um so we are going to take their square root and going to calculate the distance between them so that even if it's negative we get a distance uh but if you want it to be more modular you can adjust it according to how your game style is although after saying this I I thought that like why I did sales but anyways so we will make a variable const X is equal to position one dot x minus position 2 dot X let's copy this and copy so we will change this to y y and Y Z n z so now we have the position oh sorry we have the X and Y and Z points so we will return math Dot sqr t x into X plus Y into y Plus Z into Z here so now we can calculate the distance between the players so we are already on a race now if I don't I hope you did not see what came on the screen but uh yeah we will now go and make the current player data variable which will hold our player ID and our player data as we already know so we are going to make player ID which would be equal to the current player ID now we are going to pass the current player ID so don't worry for that piece don't beat me for that and then make in this thing make players data add current player data current player ID sorry yeah so this is the current uh player info that we are now you must be seeing we don't have this variable anywhere we don't have this variable uh we don't have this variable anywhere so we need this so we will create it here so let's call current client so this will hold the Ws uh info of the current client and we have the current player ID now and also this should be currently ready not current clear data now this info has to be passed from here so we will add WS here and we will also store the Ws info in the uh in this variable players if you have variable so at WS here at WS here and also pass the player ID here so now we receive the current client and the current player ID so uh in the current player data we are now holding our player ID and clear data so we can move on so for we will make a force each Loop for const player ID we will get the player data also from here uh yeah of object Dot entries and we will get the increase of the player data so in short we are breaking this player's data variable into player ID and the player data and then we'll get const uh either we can get the distance okay let's get the distance separately so let's get const distance is equal to calc ulate distance in Brackets we'll get the position of this player data Dot position and the second would be player layers data and the current layer ID which one is it no current layer ID and also the position of that and done so when we got the distance let's add a console.log and this can say maybe a distance between dollar by Dollar I always remember dollar sign uh Indian wrapper but yeah anyways let's add the current player ID so we we cannot like auto type it so let's copy the name from here and then we also need to pass in and dollar player ID this one and we can pass in the distance between them and the distance is the calculated distance which is distance now now if this distance is less than equal to thousand we are going to we are going to sorry for that disturbance button we are going to make a WS so basically now we need to remove WS from our array so that the players can be updated for it like we don't need to send that data to the players right and then we will make a data to be send not a string just data to be sent and we will get the current layer data so this will just I will add one line This Will omit the Ws field so that we remember in the future and then we will get clear data dot WS so we are getting the Ws from this thing this variable uh player data variable and not the data to send variable WS so remember these are small things because maybe you get issues for it to it and then we will Json Dot stringify yeah yeah and we will stringify uh the type which is player update so remember we need to update our code also for this now and we will send the data also now this data needs to be data to send which is this one uh data to send this one and then we can add and uh so that is it I don't think anything else is left oh also we don't need to send all the infos now so we can remove these things did I miss something yeah this can be removed completely and this data to be updated can also be removed now this player ID did not get used anywhere oh no it did get used here okay so most of the stuff is done I don't think anything else is left from this point okay let's go back to the game and let's go to BP game instance and get players in map so go here and here we are checking the type to the all player data but the new type which we are getting is player update so let's paste this thing here and now we are not getting a loop but as but a field itself so we need to get object field uh now I think we can directly get the values from here right no we can't let me check uh yeah we are getting the field okay okay sorry yet object field and this field name is data we can remove this array field from here and we can also remove this array if this is true then we just uh send this place Json data which field does it require oh yeah yeah okay okay understood so let's make this this and plug everyone everything here we do not need to convert it to an object now and we can just copy the same thing remove it paste it here pens go back to get players in map we can remove this thing up and here we can pass in the data do you think this will work I hope I really hope this works let's open up the visual studio code and run this uh if it says player update is not defined just rerun it and it will work and let's play connect to servers we are connected connect to servers we are connected and we got updated so this time the first update did came late uh but like that's that can be a simple fix so let's see what's the distance between the players is it getting printed correctly nope it did not get printed uh I think so I made a mistake oh sorry sorry this should have been this sign yeah this will now get printed distance uh so let's stop this and replay start replay connect to servers connect to servers play let's see if this printed now yeah it is printing so 496 uh oh we did not check the distance between our our own but no worries we can add a simple fix for it but let's see what is the distance now yeah so distance became more than thousand so let's do one thing if I uh technically if I move uh move this client now it should not update to this client so I move it here and yeah it did not get updated let me make this and this now if I come back into the range of the player we just we got updated and same way here so uh that like minor Miner bugs do have to be fixed and things have to be uh made more smoother but let's see if we move out of the range you can see the update got uh stopped so now what now we need to do is uh if the update doesn't need to be with this player we need to destroy this player uh because we don't need to update it anymore and now you see it's pretty much getting replicated correctly nice good progress let's move on to the next point now let's work on a work about uh destroying players so let's create a new function and name this destroy in octave layers and then get all actors of class and get the because we only want the proxy characters and not the main ones so we will get all the proxy characters and then for each Loop we will get allotted layer ID so what we are going to do is we will get uh we will check if this player is active or not or like is within the range or not because we are already getting this thing update proxy characters which tells you which players are in the range so after this is done now we want to update all the player like uh we want to update the current client uh which players are in his region we do not want to leave him hanging key you check it from unreal side and remove it yourself we want him to tell like ah bro you are this character is in your range and this is not so we need to update that also so let's make a const and make a nearby player IDs and then uh if the distance is less than a thousand then we will add nearby player IDs and we will dot push and we will just push the player ID this player ID is of the players other than this player itself and I think so it is of the player himself also right so we will add a check for here we will add and check uh we will check if current player ID is not equal to the player ID so we just make a check that we don't send our own ID and get our own self destroyed so after this we will update we will send the current client send Json Dot stringify is is uh near by layers and then the data is nearby player IDs here and then now we are sending the current client also the data of the place so let's get back to Unreal Engine you can stop the client here and we made this thing up so uh what we can do is we go back to event graph and we make a switch case now because our date message is getting uh big so we will make a switch case here switch on string and we will make the first case for player update so let's go back yeah we need to copy this thing copy this thing the type and clear data go back we will decode the Json like this uh we will get the type and we will not check this way but we will say check on switch on string so the first thing is player update so we can remove this from here now and we can uh just I need to disconnect this thing up yeah we can just check on type so if we will decode it after we receive we will get the type we will switch at a switch on string check what type of update we have gotten so if it is a player update then we would update that or if it is a nearby a nearby players update so we will add a string for that also so here we will get the players in map and we can directly call this update proxy players now right you can copy this thing up and we can call this directly we do not need to call get players in Mac now and for data we would be getting that exactly in the same way for both now if it is nearby things we call destroy in active players and we will pass in the data again compile and Save I hope I'm not missing anything here yeah let's go back to destroying active players and let's make a player ID array for a string array inputs must have a okay for now we will just make a empty array we will fix this let's go back so uh this player ID now we'll check through all this thing uh we'll see if all the player IDs are found and destroy the ones that are like not used so we get all the proxy characters and we will make a find a find here find item and if it is equal to or greater equal to 0 that means we found the actor or else we did not find it so if it if we found it we do not need to worry about if we did not find it then we need to destroy and because I thought someone was calling me but yeah but but because uh we do not need to worry about replication that is already getting handled we like we can just destroy it normally uh looks like everything is done right no one more thing is left we need to pass in the players IDs variable so before that let's yeah so let's get uh array field it should be a string array get a string array field and name this data and just pass it here so now we have all the player IDs hopefully so let's check now uh I think the server is not running so we need to run this so I don't know why sometimes this when we run the code first time it gives a fake error but not then it starts running so we connect to the server everything looks normal connect to the server everything looks normal so yeah so both are getting updated now let's get out of the range and that player got destroyed and even for him I hope that yeah I'm sure that player got destroyed for both now if I go back into the region you can see that player came up but this player did not came up because uh he is not sending any updates this this is a small fix so let's do it now let's go back to our uh top down Blueprints and top down character and we will now not uh we will now not check the last update position because we have already optimized the process now let's play before that restart the server can I clear this thing clear output here yeah and let's play and connect so everything looks normal everything looks normal and I'm out of the range of the player as you can see if I go back I am back in range and this time both can see each other even though this player did not move uh the player the position of the player was getting updated and I go out of the range I come back in the range I should have gone out of the range and then I should come back into the reach so this is getting uh updated and now you can also see the graph you can see uh it was this distance is getting checked because uh the check for the current player ID is after we printing after printing the distance so that's why it's getting printed but we can bring it down so if you want you can only print uh distance for the current player IDs and the player right like after we check both are not seen so now it won't get printed for our own self so that is done so we now have a much optimized process let's move on that said thanks a lot uh for watching hope you liked the video and uh don't forget to check part two if it's already released or you can join the Discord for support if uh you have any issues or stuff like that but part two would be coming soon uh within a month uh like within 15 days of this video release hopefully uh just check the Discord we would be updating you regularly on how the new video is going and thanks a lot uh consider subscribing and liking the video If you find this useful bye
Info
Channel: Betide Studio
Views: 4,893
Rating: undefined out of 5
Keywords: betide studio, unreal engine 5, unreal engine free project download, unreal engine, ue5, ue5 pixel streaming, pixel streaming unreal engine 5, pixel streaming unreal engine
Id: hUHvNSsTXZI
Channel Id: undefined
Length: 93min 52sec (5632 seconds)
Published: Sun Sep 17 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.