How to Create a 2D Card Game in Unity - Part 3 (Multiplayer Basics with Mirror)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey everybody and as far as on here and welcome to part three of making a 2d card game using unity in this video and I should say in this video and the next video we're going to be working on adding multiplayer functionality to our 2d card game if you haven't already worked through the first two tutorials in this series part 1 and part 2 I highly recommend going and checking them out as you'll understand better what we're gonna do here and why we're doing what we're doing but I'll also include the original github for this project right here where as where we're about to start so if you just want to install all of that stuff and get working here you could do that as well I'll give a quick run-through of the code so far so that you have an idea of where we're at and I'll also post the updated github of everything that we will have done by the end of this video and the next one it's gonna take about two videos to get through all the multiplayer stuff because there's a lot to cover and a lot to do I'll also recommend a couple of articles and video series that you'll want to look at to brush up on networking and we'll be using specifically a package called mirror which aims to offer a multiplayer solution for unity as there's no native solution for multiplayer in unity as of this time as the the recording of this video I'll talk about that a little bit as well so we're looking at our game screen and I'm just going to give you a quick run-through of where where we are we have a very basic 2d card game that uses the unity canvas to deal cards and allow us to drag and drop them around when I hit play we'll see that functional functionality in action I have this button that when I hover over it and click it it draws cars at cards at random from a list that we'll look at look at in the in the code and I have a random assortment of red and green cards when I well when I put my mouse over one of the cards it sort of highlights them it expands them so that I can see let's say the text on them better if I have text on my cards and when I drag one over this drop zone here here in the middle it's going to automatically add that card to the drop zone which itself is a grid and it has this really nice feeling that I'm dragging a card and dropping it in a drop zone and then the drop zone is handling the representation of that card as it's in the drop zone just like that to get there well it's taken us two videos to get there and some of the reason why is because we've had to work with the unity canvas creating these these game objects here we have a background drop zone a player area and an enemy area that are represented here on screen in the user interface there's the button that has a little text element on it and of course all of these are nested within the main canvas and we have most of these saying things saved as prefabs so that we can use them over and over again and we also have three scripts that handle all of the functionality that we've seen here one of the main ones is this draw cards script that will open here using Visual Studio and these three scripts are essential to the what we're doing here in our card game and will be essential to all our multiplayer as well and we'll be editing them heavily which is why I'm gonna I've created a new branch on the github for this project specifically for a multiplayer just to have a clean separation of our code because there's going to be a lot of changes that we're gonna do here just reminding you or welcoming you if you this is your first time watching these videos to to what we've been doing we have a a draw cards class that derives from monobehaviour and we've exposed these four things these four public game objects in the inspector one of them is card one and car two we also have a player an area and an enemy area and let me just show you that in the inspector so this draw cards script it lives on this button which is called draw cards I click on that button I see that I have the draw card script attached to it what I've done here is I've dragged and dropped the card one and card two prefabs into these open fields from these public game objects that we've declared and the player area an enemy area that exists here the actual objects because these will be instantiated at runtime we've created a list called cards that holds game objects and that when this button is instantiated we use a start function to add card 1 and card 2 to that cards list and then when someone clicks on the on the button we run a a for loop in fact instead of this being a variable let me just change this for bio C to say this is gonna be an integer we count to 5 and and that each count we instantiate a random card from the the cards game list the cards game object lists and we set the parent of its transform to the player area and we do the same with our enemy cards we instantiate five of them at random from the list and we set the parent of the transform to the the enemy area if you don't understand this quite a bit I just recommend checking out those first two videos as we'll walk through the the each step of how to do these things and why we do them but what happens is we've we've added a an on-click function here where there's a or an event I should say that when someone clicks on the but on this button we tell unity that it should call the draw cards on a click function which is what we just saw here this is called on click and that's what it's what it's drawing from when somebody clicks the button additionally we have this drag and drop script which is a little bit convoluted just because of the way that dragging and dropping works in unity I'm not going to talk about this too much because we won't touch it very much just a little bit in our multiplayer tutorial but suffice it to say that we we figure out where the canvas is when this when this the game bought object this is attached to which will be a card when it comes awake it finds the main canvas and we do some work to see if the the pointer is over the object and when or the card and when someone clicks on the or I should say when someone when someone clicks on the object when someone clicks on the card we set the this boolean up here is dragging to true and we tell unity to essentially attach the card to the pointer to the mouse pointer so that it moves wherever the mouse goes and whenever it is dropped if it's dropped over a drop zone and we've used colliders to determine whether there's a collision between this card and the drop zone then we say okay go ahead and drop it in the drop zone but if it's not dropped in a drop zone return it to its original position and we've also done some work to make sure that it's parented as a child of the canvas so that it stays in front I'll just show you this right here when I drag something we were at seeing an issue in the very first tutorial where I would drag this and we'd go behind the draw cards button or it would be go behind the enemy area or behind the player or whatever and we just if you can watch on the left side of the screen when we do this and I drag the this card it's actually being being becoming a child of the main canvas so that it stays on top of everything and and notice when I try and drag it somewhere that's not a drop zone it just goes back to its starting position but if I drag it over the drop zone it detects a collision and that allows it to be droppable we've also had to do some work with the layers of the game so that we determine what layers are collidable if you're interested in that please go ahead and check out the code as you'll see or check out the the project as you'll all of that in there and finally in this card zoom script that's the one that we use to to create a larger version of the card on Moss over and we're just saying on hover enter when the when the mouse hovers over this thing create a new game object that's twice the size of it and and when we zoom away from it on hover exit just delete that that new version of the card taking a quick look at the prefab will see all of this in action so we have the two scripts that are attached to it we have the event triggers that when a drag starts we should do the the start drag function in our in our script when the drag ends we should end that function or we should use the end drag function when hovers happen or when the mouse exits a hover we should do something and then we also have a box Collider and a rigidbody attached to this so that we can we can work with the drop zone I should also mention that we have for this for our initial tutorials we've just been using a basic image with no sprite attached to it we've just been using green and red cards so when as you've seen when I draw cards I just see red and green cards the only thing that I've done in between then and now that you're welcome to do you're welcome to keep going the way that we have or to add your own sprites if you have your own cards that you're working with but I've if you check they get help for this project you'll see the assets for this particular tutorial are in the assets slash assets folder they're just cards from my own card game which is called enter man see hacker battles I'm going to be playing a little bit with perhaps not in this video but in the next one the backs and Friends of cards so that if I'm looking at enemy cards I can only see the backs of those cards whereas if I'm looking at my cards I can see the Front's of them and vice versa so what I'm gonna do here is I've just I've added those assets in the asset slash assets folder and I'm gonna grab my card one pre and instead of there being no source image here I'm gonna say I'm gonna say here that it's this Sian underscore ping at 3 X sprite again it could be whatever sprite that you like that just means also that I need to change the color of this to white so that there's no like color overlay or I don't want to mess with that at all and then for my other prefab card too I'm gonna go in here and I'm gonna change the source image as you see there was there was none and we had that red color instead I'm gonna change that to the magenta version of this card magenta ping just do we have a little bit of variation I've changed the color to nothing just white and then now when I hit play and I hit draw cards now I see it's still randomizing my cards but now I'm seeing card 1 rather than being a green card it's this this blue card and card 2 is a magenta card and then you know this helps me a little bit better I still you know have a little bit work to do if I want to do this hover over thing but because it's not really working appropriately here but in any case that's the functional functionality that I want to see ok cool so we're all caught up and we know everything great so let's talk a little bit about multiplayer as this has been a a topic of contention for me as I've been looking for a multiplayer solution for a very long time for unity whereas in JavaScript for example I have another video up about doing a multiplayer card game using phaser as the game engine and socket IO with Express as the backend doing the multiplayer unity and I don't know that all the reasons for this there's a blog post out at that out there that's been posted by by unity that they've deprecated you net which was the multi the native multiplayer solution that they had prior to this time they have deprecated or they are deprecating it and the solution does not exist publicly yet I'm not sure what they plan to do for a multiplayer but there currently doesn't exist a viable solution that's put out by unity for a multiplayer which is kind of crazy to me but whatever I don't make up the rules so what what that means is you have to go out and find your own solution a third-party solution to do your multiplayer which to me is an ideal because I don't know how supportive it is or how it interfaces with unity and I've I've done a bit of research to figure out what's out there and you have a few options you have mirror which is what we're going to use today you also have photon photon has a unity specific networking solution called pun PU n that you can look into I looked into it to my myself it's a little bit more than what I need for this simple card game and there's also like Fox server and a bunch of other things that you can just do a search for a multiplayer unity and you'll find more than you'll ever want to know the reason why I chose mirror is it it seems to be the most streamlined and easy to use of all of the different frameworks that are out there at least to my knowledge it also is I think it's actually a fork of U net so it had it shares a lot of similarities with you net meaning that unit has a lot of official documentation that has been deprecated and isn't necessarily exact an exact copy of what mirror offers but if you get stuck using mirror you can look look up some of the unit documentation and it might not be exactly analogous to what you need but it might also provide a breadcrumb for you to figure out what direction you should be headed in to find a solution to your problem I've definitely had that experience in this project but hopefully you won't have any problems and all work out cool so before we get into the actual doing of the multiplayer aspect of this card game I'd like to walk you through a few things about why we're doing the things we're we're doing and establish some terminology as well because the networking aspect in light at least in my experience is completely different from most of the things you've already encountered in your unity career so far some of the terminology is different some of the ideas and the concepts are different and it would just be a great idea to familiarize yourself with these concepts before we tackle the the game itself we're going to do some explanation while we're in the game of course but I would highly recommend that you check out two things before we well let's say three things before we even get started if you want to just jump in with me that's fine too but it would really be helpful to do three things go to mirror - networking.com and just look through the documentation about what it does and and what you should expect when you're using mirror and what are some of the best practices when when doing so I'll talk about these in great depth while we're well some of them in great depth while we're cracking through our code but it would be a great primer for you as a developer just venturing into the multiplayer sphere to be familiar with some of these concepts the second is this very cool article on game dev Academy on how to create a multiplayer game in unity this is this particular tutorial is made using unit Oh actually no it uses mirror yet some of the things that they discuss in it are not exactly the way that unit works now I don't know if it's been updated or it's not I just I'm not even sure if you ran through this entire tutorial if you'd get exactly where the authors of the article want you to get to it's not impossible of course but it runs you through some ideas about what the network manager does how to in spawn items on screen what the player object does how to use a sync variable and even if it's just you just read through it I think it will give you a give you an idea of how mirror works and why you should be using it it doesn't work perfectly for our purposes which is why I've had to create my own solution for this simply because it it it operates on the idea that you the player are an object in the scene you're this like little spaceship and trying to fire at enemies which is not what we're doing at all where we're as players were actually removed from all the game objects because we want to drag and drop them all over the screen so it requires a bit of a different approach but in terms of base a basic entry point to mirror and understanding how it works this is a great article I'll link it in the description for this for this video and first gear games has a wonderful tutorial series on YouTube which I'll also link in the description for this video called unity multiplayer with mirror it's like what 11 videos 12 13 14 videos that you don't have to watch all of them but they're there I found them to be really helpful used resources in understanding the API that is available to you I should say that the mirror discord community also has been very helpful which is where I found out a bit about these videos so if you have problems check out this video series definitely look at the mirror documentation and and visit the mirror discord because they're very helpful over there cool great all that's out of the way let's talk about what we're doing here so in in mirror and in other paradigms of multiplayer networking we're gonna presume that we're we're gonna have two players that are entering this two player card game on the one hand one player is going to be a client just a standalone client that is I'm going to attempt to connect through the network to to play a game on a server that's that's a general architecture of how things work the other player is not only going to be a client but they're also going to be running the server in a peer-to-peer networking situation so if you're playing let's say you're playing as the client and I'm also playing I'm going to be a client too but we need to host the game somewhere so where I'm gonna be the server and the client at the same time and that makes me what's called a host so we're going to use those terms over the course of these next two videos saying that I'm the host meaning that I'm the server and a client and you also are going to be a client but you're not a server so in in some some ways I'm fulfilling two functions or my computers fulfilling two functions whereas your computer is just being a client that is going to take us into the wide world of authority which is something that might make you bang your head against the wall as it as it has mine but once you understand it it will help smooth a lot of the rough edges of attempting to get a game up and running with mirror immunity if I have authority over an object that means that I can do certain things with it based on networking often times the server has authority over everything so if we ask the server for example make this a bunch of cards the server will have authority over it and if I'm playing as a host remember I'm also playing as the server so that means that I might have authority over those cards but if I ask the server to spot a bunch of cards on both of our screens then you might have a bunch of cards on your screen and you might say well okay I want to do some networking stuff with it and unfortunately you won't be able to do anything with them networking wise because you don't have authority over those objects that's one concept that will return to time and again throughout the tutorial and it's worth looking through these this documentation to understand the authority aspect as well as local players I sorry whether or not you're the local player or whether or not you're the server or the client there's are a few different things that will like I said encounter time and time again and it would be worth just looking over these this documentation and getting a general idea before we we dive in so a lot of this will encounter as we get through the code so what we'll do you and I together we'll go to the asset store and you're going to want to search for mirror networking I already have it in my saved asset so that shouldn't be a problem and what we need to do is we we need to import mirror I'm just going to my assets here and one of them is mirror I'm gonna download that if you if you don't have it here obviously that's because you haven't searched for it so go ahead and search for it in your your in-game asset store and then after its downloaded I'm going to click import it's gonna prepare a package for me and when this dialog box jumps up I just want to make sure everything's selected I'll click import it'll go ahead and do that and I'll notice in my project pane down here that I'll have a new folder called mirror and we'll look through some of those things that are available in there for you although we won't really touch any of them we're just going to be using the functionality that comes along with that with that package something else to to notice is that I'll be using the word spawn which is what mirror uses to indicate what we usually say instantiate a game object and mirror when you instantiate something that's all well and good but if you want the server to handle it and to to create it so for everyone to see and to play with you have to spawn it so you might hear me say spawn and don't want to be thrown off if you're used to hearing instantiate so you've you see here on the left hand and left hand side of the screen I have a new mirror folder in the assets folder just taking a look at that I have a I have an authenticators folder compiler symbols components editor examples icon plugins and runtime you can look over this at your own at your leisure the only thing I want to point out to you is if you go to the examples folder you'll see several different examples of how to do stuff in in mirror for example if you need a chat service you can check out the chat example if you want to look at pong that's a great idea there's a tank's example that has a very simple tanks game that's not not too dissimilar from the way that that tutorial that I showed you earlier on game dev Academy works so check those out if you get stuck or you just want to kind of grow what mirror does otherwise the whole thing starts when we we now that we've installed mirror the whole thing starts when we add an empty game Jeb ain't game object on our screen and we're gonna call this network manager so empty game object just honor on our scene and we're gonna add a component to it which is called a network manager this network manager is what's going to allow us to do all of our networking for our multiplayer game I think there are ways for you to create your own custom Network manager and do a bunch of stuff by digging into the specific code for the network manager we're not going to do any of that in our in our game development we're just going to use what comes out of the box for most of this stuff but just there's a whole world awaits if you're interested in it the two things that are important here that we want to look at are the player prefab area and the the registered spa noble prefabs mirror presupposes that you have a player in your game that is going to do most of the the actions in your game and is going to have the authority to do those actions if you think about like a tank style game or that space invaders type game that we looked at with the tutorial if I'm like a spaceship that's gonna be my player prefab and that player prefab is gonna do stuff like create bullets and do damage to enemies and all that stuff we don't have that particular situation here because we don't really have a player I'm the player and you're the player but we don't have a representation of us on the screen so it's gonna be a little bit different the way we handle this but still we're gonna have to create a player prefab and drag it to this player prefab field and anything that we want to be spawned belen the world for example if we want to be able to spawn enemies or bullets or elves or anything that needs to be in this list and we'll add our cards to this list so what I think we should actually do first is add one other component so we can see what's going to happen we're going to add the network manager HUD or heads-up display right here and that allows us to do - to see the network manager in action when we play a game as you can see there's a telepathy transport script here that is working with port 7777 so when the game starts it's going to start listening at that the server is gonna listen at that port so when I hit play now before where we didn't have anything here now we have this nice little heads-up display that is the this we would use for development purposes only obviously as a in production we might use some other sort of solution or change things so that it looks differently but I can choose whether I'm going to be the host where we said that I'm a client and the server whether I'm going to be the client or if I just want to be a server only which is also an option that we won't be working we won't be doing this we'll be creating our code in that fashion we're gonna be presuming that one person is gonna be the host and the other person is just going to be a standalone client but you could just create a server and have people log in to that server and handle your your game architecture differently than we're going to do here but if I click host now it says server active transport telepathy server port 7777 and the client address is the localhost that just means that the it's listening on seven seven seven seven and for a client to to to attach to it and that's not going to happen until I have another client to attach to it so nothing's going to happen here it's like stop just to show you if I hit client it's gonna say connecting to localhost but there's no there's no server anymore because I stopped the server and it's just gonna stop its operation because nothing's happening so that's that's going to be the general workflow that will will have cool so you've created our network management network manager before we do anything else let's just let's create a an empty player object let's call this the player manager and as I mentioned well let's do a few different things let's let's go to our let's close our mirror folder let's go to our prefabs and let's create prefabs of a few different things let's create a prefab of my player manager let's create a prefab of this button and what else can we do let's let's make sure that the prefabs that are exist for our background and the drop zone and the player area and enemy area they don't have any overrides meaning that we haven't made any changes to these objects here that need to be applied to the prefabs okay great now that we've done that we have all our prefabs here let's go to this to our network manager and under the player prefab area field let's drag that player manager we'll say that's going to be our player that's going to represent us in the game and we see that player we get an error that network manager player prefab must have a network identity and that's a great segue into talking about now we have our network manager but we also need to indicate to to unity or specifically to mirror which of the game objects that we are using in this scene which of them are things that we want to do take Network actions on the background is going to be the same for every player that joins this game but as an example so I don't need to add a network identity to it but my players do if I if I'm thinking that I want to do Network actions with this player then I need to have a I need to attach what's called a network identity to it so that American can perform network operations on our network actions so I'm just going to add a component called Network identity and you'll see it just adds a basic script here and it has a check mark to say whether or not it's server only we won't be using that because we want our players to be both on both clients and we'll also add another component here which is called a network transform I'm not actually sure that this is necessary for your player object if we're not actually having a representation of the player in the screen a network transform is used or the the component the script is used to determine where your your game object is on the screen so that it can sync it up between my client and your client the server does that and since we don't have a representation for it I'm not sure that is actually necessary for your for your player object but who knows I actually haven't tested that so it doesn't really make that much difference I can delete this from my scene because I don't need it I'm gonna instantiate it at runtime and what I'll do now is I'll go back to my network manager and I'll drag the player manager to the player prefab and what did I do wrong oh I did exactly what I said that we shouldn't do which is I added that I added all that stuff to the object and not to the player manager itself so here's a here's a cheat if I just say Network transform it will add the network transform and also the network identity to it in one fell swoop so I don't have to do all that again back to my network manager dragging my player manager to the player prefab and there it is and I'm also going to add a few other things to the network manager and these are the things that I want the the the network or the server to be able to interact with over the course of my of might and we'll see I'm gonna save you some time for from having to search to understand which ones are going to be needed to be managed by the server and which ones are just going to live on your screen and just tell you that I need to add my cards I need to add my button my player area my enemy area and my drop zone so I'm just going to add all those here what did I say those are six items so I've got two three four five six things and to each of these things on card one I need to add a new component and I'm just going to add the network transform remember that's gonna add the network identity and the network transform here and while I while I'm doing this I'm also going to click on clients Authority if I hover over this there's this text it just gives me a tooltip that says set set to true if moves come from owner client set to false if moves always come from server that just means that I want the client to be able to have authority over this object rather than saying the server is only ever going to do the work I go to card two and I add a new component I add that Network transform which also adds a network identity I click client authority now I go over to my drop zone and I do the same here I'm gonna add a network transform and in this one I'm not going to click client authority see why in a bit but just to explain it here the players never actually do anything with the transform or the the position of the drop zone they are going to move things to the drop zone but the server is gonna handle everything else that has to do with the drop zone so I don't need the client to have authority over it it's not like I'm moving my drop zone around with my as a player and that goes the same for the enemy area and the player area at an Annette Trick network transfer them to both of them now I go back to my network manager and I'm just gonna drag my card one my card to my drop zone my enemy area my player area and we need to do our button as well where are you button network manager and add the button great now this just means that my network manager is prepared to spawn these prefabs when necessary either through scripts or when I ask that to or whatever and it has my player manager as they player prefab when I hit play what you'll see is that there's nothing really going on in my screen until I click host and then all this stuff is instantiated as it should do so you might be scared when you first hit play and you're just like wait a minute where did all this stuff go but you know rest assured that it's all just you know it's it's all still here it's just that now with that we've given the server or mirror control over it it instantiate it at run time rather than rather than when you hit play so when I hit host it comes back on and I have the same functionality that I did before okay that's a good time to go get a drink of water or whatever you need to do because we're now we're gonna start talking about code if I looked at my original scripts I just have these three basic scripts that we talked about at the beginning of the video and I'm gonna need to do quite a bit of work to make it so that when I am playing the game and you are playing the game we're able to communicate among each other and I think it's this is actually a really great time to demonstrate what your work workflow is going to be like when working with unity and mirror in a networking situation if you haven't done any multiplayer in immunity which I hadn't before taking on this project it might come as a surprise to you that you're not able to just do everything from the comfort of your unity editor as you have been able to because you need to run two executables so to speak you need to run two games what I need to do is I need to build the game and actually run it every time I want to attempt to do some networking because right now I only have one client here that's also operating as a server it's a host to create another client I need to actually bill I need to make the game and run them both simultaneously so that they can communicate with one another the weight that I'm going to do that is I'm going to go to file build settings make sure that my my sample scene is included in in the scene and I'm going to hit build and run and it's gonna require me to create a folder I'm just gonna call it let me see they create a folder here called build and I'll use that folder to build and then it'll take some time to do that so this might lengthen the video time of this video because we're gonna wait for it to build every time that it that it does that and you'll see if if there's some sort of error it'll throw you an error oftentimes if you still have the game running it'll throw you an error so just make sure you've closed whatever game you've already built I'll show you what that looks like but it goes ahead and because we said build and run it will build the game and then immediately run it and we'll see that I'm now at the same screen as I was before when I click on land host it starts the game I can just allow access here it starts the game and I have the same functionality here as I did before but when I go back to my editor if I hit play remember how we hit after we did this we hit client and nothing happened well now I'll hit client and you'll see the client is putting to the localhost it starts the game because it's it's connected to the server or our the game that's running out here is it's playing that we've selected the it to be the host so it has provided a host for the our editor to connect to and now we have these two games playing in tandem I can draw cards here I have the same thing happening as I have on my my built game and let me just stop these processes and switch it around so you can see what's happening in the editor I'm going to say I want to be the host in the editor remember that means I'm going to be a server and a client and if I go to the console I see that I'm thanks for using mirror it lets me know that the telepathy transport is initialized and that it's listening on port 7777 and it says start host client called so we've we just means that the the host client has started and then in the the the built version of the game I hit client and the same thing happens as as before it just starts the game and I'm not really getting any any logs here so it doesn't really tell me anything but what I want you to know is that these two games are now communicating with one another over localhost but they don't know anything about each other because that we haven't told them to do anything in terms of networking so you know nothing will work but it is successfully they are successfully communicating with one another right now and that's cool so I'm gonna make sure to hit alt f4 to close this this game window if I don't if I if I don't and I try to build the game again I'll get an error stop the game from playing and next time we do this rather than going to file build settings all that I'm just going to hit control B which is going to build and run my game save you a little bit of time and then we're gonna do that every time we make a change to the code that we want to test super super annoying but it's just what you got to do to make it work okay great the first thing we're gonna do is we're gonna figure out how to how to change the onus of this draw cards function train change the functionality of it so that it doesn't just happen on my screen that when I click it it's gonna it's going to ask the server to spawn those cards so that everyone eventually can see them it doesn't do me much good to have cards on my screen that only I can see and cards on your screen that only you can see and we never see each other's cards like there's really no point than that there might be some reasons for me to only see my cards for some time and you only see your cards for some time and we'll get into that later but right now I just want to see how I can generate get the card cards to be generated by the server that everyone can see them so that's going to require me to do a couple of different things the first one is I need to go into my into my code and I go into my draw cards function remember this was the one that's on our button I actually want to move all of this over to a new script which we'll call player manager so let's create that now let's go to our player manager prefab which has not much except for the network identity and transform attached to it let's add a new script and let's call it player manager spell it correctly and this is where a lot of the code is going to live that we are using and I'm actually going to make sure that it's it's gonna create this in my root directory for my assets folder so I'm just going to move that to scripts cuz I like everything in one place and then in the scripts folder I open my player manager script and it's got nothing in it which is great and I'm gonna move a lot of this code over from my draw cards script we're still going to keep the draw card script but we're gonna change it quite a bit and the first thing I actually need to do is I need to add a new namespace to this because the standard unity libraries aren't gonna know anything about what I'm gonna try to do here so I'm gonna say using mirror and we mentioned at the beginning of the video that ours our scripts derived from monobehaviour we need to change this with any script that involves networking and we're gonna say that we're deriving from network behavior and that X if you're using the unity toolset that comes with Visual Studio if you've installed it you will see that the autocomplete is great it will just know that I'm now that I'm using mirror I want to be deriving from network behavior and I'm gonna move a bunch of this stuff from the the draw cards script namely this this stuff here I'm just gonna control X and pasted it right here above the start function what else am I going to do I'm going to well I'm gonna use this this cards dot add as well but I'm gonna put it in a different place and I'm gonna use this on click but I'm also gonna put it in different place so let's just wait on that for a second I'm just moving the functionality of this stuff over to my player manager and I'm also going to expose a public game object called drop zone there's a couple of things that we can use right now right off the bat from this script for example when I go to my player manager here in my prefabs folder I have this player manager and I have card one card two player area and a merrier and drop zone the card button cartoon that just these are these two cards I can just drag and drop them here because these are the cards that I'm gonna want to instantiate or to spawn when my games ready but the player area enemy area and drop zone I'm not actually going to spawn them using the player manager they're going to be created at run time by the network manager so I need to be able to find them similarly to the way that I found the canvas as we've done in a previous video when we were we were doing we're trying to find the yeah we're trying to find the main canvas during the the card zoom event when we zoom in on a card I think we actually also do it with a drag-and-drop method so we're gonna do that same here with the player manager we're gonna say that instead of the start function here we're going to use one of the that networking functions which is called public void override on start client and we're gonna say here I did this backwards public override void on start client it derives from or it uses all the same stuff as the basis on Start client this just means that what we're doing here we're saying that when the client starts when and they're they're different there's a different flow that you can look at when you go to I can't remember actually where this lives on the network on the network mirror networking website or if you go to one of these videos by first gear games they go they gave a really great in-depth explanation of what's the video I'm looking for network behavior the start cycle it says what happens first the server starts and then the client starts and then the local player starts and then your normal start function starts and then no then it's awake then it's start or whatever it lets you know what the what the start cycle is every time that a server starts or a client starts what's the order of operations and what we're doing here we're saying instead of the start function we're using on start client when the start when the when the client is started we want you to do this thing we want you to override the on start client that is already packaged with mirror we want to we want to do everything that the on start client already does but we want to override it by adding these specific things we want to say that the player area is equal to game object find and then a string called player area so that just means find where where's the player area find it for me and store it in this variable called player area enemy area equals game object find enemy area find that as well you remember that's been it that's been created by the sir and drop zone find the drop zone that has been created by the network manager find these things when the client starts now this is this might throw you a little bit for a loop as as we have to think in the minds of three different things we have to think of the server we have to think of the client that's on the server and we have to think of the client that's not attached to the server that it's a it's a client only and for the sake of these videos we'll say that I'm gonna be the host I'm the server and a client and you're you're a client and you're I'm gonna start a game and you're going to attach yourself to that game and start communicating with the server that way so but all of this stuff lives in the same script like I'm gonna send you the same game as I'm playing here it's it's just mirror that's gonna determine who's this or will determine through mirror who's the server or who's the host and who's gonna be the client so it might be confusing to see all of that in the same script because you might say well the server should have a different script and the the clients should have different scripts shouldn't they and the answer is well kinda but because we're using the same game we're putting all the script all of the code in one script and then we're asking mirror to determine what to do whether or not what to do based on whether we're the host weather or server and a client meaning the host or whether we're just a client so when I do this here when I put in brackets server this means only the server is going to do this function if I did client that would mean only the clients gonna do this or only a clients going to do this and for the server I'm gonna say public override void on start server should do this cards dot ad card 1 and card 2 which we've already established what those are so the server is going to handle the creation of the cards so we need to say when the server starts hey server add these to your cards list the client doesn't need to do that and in fact if you try and call on start server with from within your client without this server tag I think it throws you an error I think I encountered out myself so don't do that great so now the server is gonna handle managing the cards and and what they should and the card list that we're going to draw from we still have this on click function that exists in our on our button that's now you know not going to work cuz we've deleted a bunch of stuff so what we're gonna create here is our first real like Network code that's that's actually gonna be pretty fun it's called command we're get we have to tag it with command and we're gonna say public void CMD deal cards create a function let's talk about this in great depth so to if we think about the client-server relationship forget about host for a minute if I want the client to ask the server to do something I need to use this word called command if I am trying to do anything Network related that the server needs to handle but I'm asking from a client authority perspective I will use a command to do that when you're using a command and it could be something as simple as change this number or update my position or I don't know you think of something I'm gonna use a command to do that and with mirror I have to do two things here I have to use this command tag in brackets up here and if you hover over it you can see call this from a client to run this function on the server and I have to call it I have to preface it with CMD capital C and then lowercase MD and then deal cards or whatever your your function name is it has to begin with CMD for it to be run correctly as a command if I'm instead creating a function from the server that I want all clients to run that's called a remote procedure call or an RPC we'll deal with that in a second just know right now that if I want the server to do something for me as a client I have to run a command and this command deal cards is going to be pretty much identical to the function that we have here or the loop that we have in on-click I'm just going to control X and control V this and paste it and I'm saying for int I equals 0 I'm incrementing I up to 5 I have a game object called player card I'm going to instantiate it I'm gonna set the parent to the player area and you know I'm gonna do the same for my enemy cards now let's consider this this worked when I was playing as a single player with a single game but what's not gonna work here is like half of this code the reason why is I'm gonna instantiate cards but what that's gonna do and I don't think we need to look at it in this video you can play with it yourself it's just going to instantiate a bunch of game objects in my game or it might not even not even do anything at all at best it will just instantiate it in my game and it's not going to show in your game which is the whole point of this exercise furthermore it might set its parent as the the the player area transform meaning that you might recall in in an earlier video we instantiated our player card but it didn't show up anywhere on the screen because it was just instantiating here on the in the hierarchy but it wasn't it wasn't setting its parent to one of the either the player area or the enemy so we couldn't see it but this isn't gonna do us much good here because it's going to set its parent on my screen where the card wasn't an she ated but it won't do it on your screen because your screen hasn't been told to your game hasn't been told to do that so we need to come up with a solution to that and I'll show you how do we do that in a minute the first thing we need to do here is actually we're just going to delete this whole enemy card thing because it's it's not going to be of much use to us because we're your your cards are gonna be my enemy cards and my cards are going to be your enemy card so we're just delete all this stuff and we'll say instead of calling this a player card for 'yes' sake let's just call this card we're still going to instantiate it as a random range between the between 0 and the length of our cards list and we actually don't need a vector3 you could leave it as e as you want but we need a vector to because it's a 2-d game so leave that if you like and then I have to change this reference to player card is just card transform and I'm actually you know what I'm just gonna delete all this stuff right here because I don't need it I'm gonna say I want to instantiate a player card or 5 of them in fact and I'm gonna say network server dot spawn card comma connection to client and this is where we get to talk about authority to spawn a object using mirror which means I want the network server to create a card in everybody's client that everyone can see and and potentially play with or work with I first have to instantiate it and then I spawn it and I use network server dot spawn and then whatever the object that I just instantiated the second parameter here is connection to client and this determines this allows me to determine that the authority for that object is going to come from the client itself that just means that when I when I spawn a card from the network sir I might run into authority issues if I try and do something like let's say I have a command on that card which we'll see in a moment that I want to run and I and I want the server to run that command well I might get an error because the server spawned that card and now as a client I'm trying to to use that card to perform some work for me to run a command for me and the server might say and you don't have authority for that I made that that object for you I spawned it for you and I have authority over it and so maybe the person who's playing is the host who's the server and the client might have authority over it but the person who is just a client will not have authority over it so you're not able to perform network actions with it with this network dot servers spawn a network server dot spawn I'm spawning the card and I'm saying assign the authority to the client that it's connected to and in that way I made it smooths the edges for me so that I have the proper authority when I'm trying to do something with that card that requires Network actions will see that in play that's all well and good in fact let's just save this and well we need to attach it before we do anything we need to attach it to the the draw cards function here in the the draw cards script where we deleted everything we need to do the same thing that we did in the player manager script let's say using mirror and we need to derive from network behavior behavior instead of mana behavior we don't need the start function here but what we do need to do is say public player manager player management we're saying there's a script out there or there's a class out there called player manager and on click instead of just dealing cards we're gonna say network identity is the type we're going to say a little little lowercase Network identity is equal to the network client dot connection dot identity took me a long time to figure out how this works so I'm just going to tell you that what we're doing here is when you start a client that client has an identity and we're saying we want to store that identity the that is of that clients connection in this variable called network identity and the player manager that we're looking for is equal to the network identity dot getcomponent player manager this is analogous to how we at runtime we say hey find that player area or find that enemy area find that drop zone we're not able to drag and drop our our player manager because it doesn't exist at the time before runtime so we're saying we're saying in a similar way in our on click method on the on the button which is called draw cards we say find me that that player manager that exists in my client that is attached to the the network client connection and when somebody clicks this button run player manager dot CMD deal cards which is this function this command that we created here let's make sure that's still attached to our button because on our button we changed it doesn't know what the player manager is because it doesn't exist in our scene yet remember and yeah so it's still great we've done this correctly so when somebody clicks it should run draw cards dawn click and the draw cards dawn click does everything that we just said event it finds the play the player manager through the network identity and it hits command deal cards which is this command over here remember your command is is a function that is run on the server by request of the client there's another way of doing this that we might encounter but for now this will work for us sometimes you wrap this in another function which is like let's just call it deal cards I'll show you it'll be like deal cards void deal cards well it would have to be public but whatever and you would say if has authority if has authority command deal cards you might see that as well just to make sure that the the thing has authority before it tries to run a command but we don't really need to do that right now you just might encounter that in your adventures ok saved everything save the scene hitting control B to build and we'll see what happens I don't expect much from this but it just want you to get used to the workflow when we're working through some of these things and I'm happy to say that our our draw cards method is complete so we don't have to do anything with that ok so my game is running I'm gonna use the built game as the is the host and I'll go back into the editor and run this as a client and now when I hit draw cards nothing happens and I hit drop cards nothing happens perfect that's actually exactly what we want nothing happens here in the build scene in the built game and nothing happens here in the editor scene irrespective of whether or not they're the hosts of the client but what we do see is that we have all these cards instantiated here on the side and we're wondering well where did they go I did all that work in the previous two videos to make sure that they were populated underneath these that the enemy area and the player area well the fact of the matter is that when you instantiate them on the server or when you spawn them from the server we knit and we now need to tell each of the clients what to do with those cards and for that we're going to use a remote procedure call just close this window so that it doesn't bother me later and a remote procedure call as your as you'll recall is what we do when the server tells all clients to do a thing it's the kind of like the opposite of a command and we're going to do that in a in a similar way as we've done before and we're going to say with the command we're gonna say we delete my update method we're going to create a tag called client RPC remote procedure call and we're gonna call it a void RPC show card and it's going to take two parameters game object card string type okay so just like the command I need to have a tag up here that's that's called the client RPC if I put my mouse over it the server uses a remote procedure call RPC to run this function on clients and just like a command I need to have a little prefix here rather than CMD it's RPC so whatever your function name is it has to start with RPC and I'm passing it a game object which is we're calling it card and a string which is just going to be called type we'll see why in a second and we're gonna say if type equals equals dealt now we're going to run that check if has authority card dot transform dot set parent player area dot transform false okay else card transform dot set parent any area dot transform pulse okay what is the same it says we're a sample just gets a type of card and we're saying if it's a card that's being dealt then we go into the next the next level of this if statement if an if the client that if the client that this player manager exists in is that it is attached to then if it has authority meaning if it's my card then go ahead and set its parent to the player area and we as you recall from the previous video we've said false because we don't want it to keep its world position we wanted to have a new world position that is set to the the parent world position or if it doesn't have authority meaning if it's not my card put it in the enemy area transform that's where I want it to go and we'll see what that looks like after we call this so you'll recall in the command deal cards we've said hey server deal me cards and then we'll say we'll call this right underneath that and we'll say our PC Show card and we'll pass the card and we'll say that it was just dealt okay so when we when we click the button we issue a command to the server from the client saying deal me cards please and give me authority to them in my client and then run this RPC show card the server is told to run the RPC show card that says go ahead and show all these cards show this card on the client and we do this five times show this card on all clients if the client has Earth has authority and remember you'll remember the cards that I'm dealt I have authority over they should be set to the player area if I don't have authority over them that means that were those are somebody else's cards set them set the transforms to the enemy area okay no I don't want that I want this okay let's save this and see if it works well I'm gonna hit ctrl B and if you just want to see if it works on the the host you could very well just run the editor run play and the editor select yourself as host and run it but I want to see if it works for both players right now here I'm gonna click land host and in my editor I'm gonna hit play and I'm gonna select land client now the two clients are connected to one another I'm gonna hit draw cards here in my my server or my host and I'm really happy to see that now they're appearing as they should on the bottom of my screen in my player area and what's super cool and a really good feeling is that in my client in the editor I now see those exact same cards in my enemy area rather than in my player area so check it out I have four of the magenta pings and one of the the blue pings and I have the same thing in my my client when I hit draw cards in my client I get a different set of cards because you remember they're randomized and I go back to my server and wall out there they're all here well the gang's all here folks we have we have two Pink's one and one blue two Pink's two Pink's one blue and two Pink's that lets me know the networking is working the cards that I have authority for are being displayed on my screen in the player area the cards that my opponent has Authority for are displayed in their own player area but they're displayed in my enemy area which is what I want that's the functionality and vice versa awesome that's working give yourself a pat on the back because that's awesome and it takes a some thinking to do good okay the the next thing that I need to think about is well you'll recall I shouldn't have closed that screen but whatever you'll recall that when I when I'm a host here or if I'm a client when after I draw my cards I can drag and drop stuff in my in my client but I can tell you right now this won't work in your in the other client like if I'm doing it in my editor it won't work in the standalone version in the built version and vice versa because I haven't told mirror what I want to happen upon that case so we need to deal with our drag and drop script so what I'll do is I'll go into my drag drop script you'll recall this is attached to all cards and I need to change some things to make this work let's do that now so I have a public game object which is the canvas and we find that main canvas on start I now need to add also the drop zone because I didn't have to work with that in my single-player game now that it's instantiate by the server I need to find it so I'm gonna say public game object drop zone and in my awake function I'm actually the changes to start because I've had a little bit of wonkiness when it comes to the awakened start function with that start cycle when your client starts and the server starts and all that so just change this to start and my canvas is going to equal to to be equal to game object fine main canvas the drop zone is going to be equal to game object dot find drop zone and before I do anything else I also need to make sure that I add the name space using mirror and because we're doing networking stuff I need to derive from network behavior okay now we might run in with into some options with authority here because when we drag and drop cards on the screen and they appear in other people's screen at other peoples screens at least that's what we're about to do we might run into the problem where I drag and drop a card on my screen it appears in your screen and you're able to drag and drop it as well but then when you do that things screw up because you don't have authority and like the whole thing just goes bonkers so we're gonna we're going to establish a check that determines whether or not I'm able to drag this thing by saying by whether or not I have authority over it so right in my these private boolean declarations up here I'm gonna call something I'm gonna create something declare a boolean called private pool is draggable and I'm going to equal that to true when this when this game object is instantiated created for the first time just set that to true and in the start function immediately I'm gonna say if exclamation mark has Authority meaning if it if this client doesn't have authority set is draggable to false you notice if you look into the start cycle there's like I don't remember what the order is but it's like on start server on start Authority on start client on start local player there's a certain order of operations that we that we talked about and there's a specific point where it's determined whether or not the object or the client or the player or whoever has authority and your start function is going to occur after that so we're saying so by the time we get to our start function of this object we know whether or not the client has authority over this object and I'm saying if it doesn't have authority just set is draggable to false so I won't be able to drag it everything else stays the same here until we get to our our start drag function we'll get some errors if we don't do this so I'm saying I'm gonna say if exclamation point is draggable return that just means if this thing is not draggable like it doesn't have authority for example just don't do anything go back and same in my end drag function I'm gonna say if it's not draggable return go back turn away from here otherwise if it's draggable go ahead and do what we're about to do we're gonna stay this the the rest of this stuff is going to stay this stay the same we're just gonna we just need to think that if I'm if I have authority of the over the object which I should because it's been instantiated on my screen then I'm gonna be able to drag the card around the screen and and if I drop it over a drop zone it should you know fall into the drop zone when it falls into the drop zone that's the key moment where I need to send it in from information to the server and say hey server card played and I need you to replicate this on the other person's screen so that we all can see what just happened you might have a different use kinase in case scenario maybe you want it to this to happen in your update method so everyone can see your card as you're dragging it around I don't know that's really up to you but the the base functionality we're working on here is that when the card is dropped we should send a message to the server to replicate that on the on all clients so I'm saying transform set parent to the drop zone which is happening locally in my client it's not happening anywhere else I'm gonna set is draggable to false meaning that once I've played my card my card no take-backs I have to leave it there and I'm gonna find the network identity just as I did in my my button my draw card script and I'm say network identity lowercase network or camelcase network identity is equal to the network client dot connection dot identity find me the network identity that is a that exists on the client that the client connection in my client remember and I'm going to say the player manager is equal to network identity dot good component layer manager so find my player manager next to the find my player manager that is in the client that I'm working on right now and I realize that I haven't declared my my player manager I need to do that up here I'm calling this a public player manager and I'm calling it player manager because it's a script it's a class it's it's not the it's not the game object that the player manager is attached to I want to I want to work with the class itself just call this player manager ok now I can work with that down here so I found the player manager and I say player manager dot play card game object not big case lower case okay I haven't created this this play card function yet I'm just saying when I drop the card run this this function or method on the player-manager attached to the client that I'm working on and pass in this particular when I say just game object that means this game object the drag dropped is is attached to script is attached to a card and I'm saying well pass this card up the chain because you're gonna need this now I need to create that card in my that function in my script on my player manager so I go over to my player manager and I'm gonna create a new a new function let's do it under this command deal cards pin well it's gonna be called let's do it this way that I mentioned before public void play card game object card oops don't need all that we're doing this a little bit differently and we'll see why in the next video we're just doing a little bit of setup to make things easier on us later and in play card all I'm going to do is I'm going to run another command called command play card and I'm gonna pass in that same card let's follow me for just a second and then we'll we'll get there in a moment underneath I'm gonna say I'm going to create a command called public void oh actually I don't think this needs to be public we can just call it void command play card and pass to it the parameter of a card which is a game object and in it we're gonna call RPC show card okay before we go any further let's let's explain what we're doing here when I drop the card I find the through the network identity I find the player manager that the that is in my client and I when I drop the card I say I want you to run play card from the player manager and I'm passing to you the game object the card that this script is attached to when player manager receives that request play card it has it receives the game object which is card it is then going to run command play card similar to our command deal cards here but we've wrapped that in in kind of like a helper function that's gonna do more work for us in the next video that command play card is set up very similarly to the command deal cards function but it's private because only this script needs to see it and it takes the game object card and all it's going to do when it receives command play card it's going to it's going to use the RPC the remote procedure call that we've already created RPC show card and it's going to pass to it the card that's you know it's just been moved from the draw sorry the drag drop function to the play card function and then now to set command play card function it's passing that same information to RPC show card and it's saying that it's also adding the string that this card has been played rather than been dealt an RPC show card we need to just add a little bit of logic we've said if the type of the card is that it's just been dealt do this stuff and we're saying else if the type of the card is equal to equal equal played we'll say card got transformed got set parent drop zone dot transform and again we'll set that to fuss because we want it to take the drop zones location and that's it that's it for now we're good to go on that so if I say if I look at my card drag drop script I've asked the player manager to run play card with this game object attached to it and then the play card function passes that information to command play card and then command play card commands or ask the server to then it gives the information of what card was just played and it says okay now use RPC showcar to get every client to show the card that was just played by setting its parent to the drop zone within that client now I've saved everything I'm gonna build it take a little while to build as it does that I'm gonna hit play here in my editor I'm gonna start out as a host on my built game and as a client on my editor I hit draw cards I see the same functionality here where my player cards are here or the let's say this is you these are your cards they appear as these cards on my screen and then I hit draw cards on my screen and they appear on your screen just fine great now I'm gonna draw a card from my player area on to the drop zone and drops in the drop zone and it appears in your drop zone whereas I'm trying you can't really tell but I'm trying to drag my cards from your screen for the opponent area and I can't do that nor can I do that here when I'm drawing them from from your cards because I don't have authority over those cards you have authority over your cards I have authority over my cards and and nobody is able to to move anything once the card is dropped because I what we did that little check that we said when the cards drop just make is draggable false so I did that now you drag your card and drop it and it shows up in my screen I drag a pink card there's another pink card there you drag a blue card and it's working great that's exactly the type of functionality that we want to have and if you have other things that you want to happen when your your card is dragging to drop that's what you would do so there's a few things to iron out here for example let's say that I want my cards I don't want you to be able to see my cards when you're when they're dealt to me and I don't want to be able to see your cards well maybe I do want to see your cards but that would be cheating you don't want to seem up you don't want me to see your cards when they're dealt so instead we want to have card backs and maybe there's also some other information that we want to sync I think that's pretty good for this video so let's continue in the next episode of creating a 2d card game with unity and we'll pick up right here right where we left off so expect that and I'll actually link that at the end of this video and I hope this has been helpful for you if it has please be sure to like it and subscribe to my videos for more you can also follow me on twitter and check out my books in games and we'll see you soon thanks for watching
Info
Channel: M. S. Farzan
Views: 27,823
Rating: undefined out of 5
Keywords: coding, programming, learn to code, javascript, python, c#, c++, game development, html, css, 2d games, 3d games, learn programming, beginner coding, coding tutorial, entromancy, m s farzan, 2d game engine, react, unity, godot engine, game maker 2, construct 3, phaser 3, 2d game framework, what 2d game engine should I use, unity 2d, unity 3d, card game, tcg, ccg, trading card game, collectible card game, multiplayer, mirror
Id: X7rKFVDGT64
Channel Id: undefined
Length: 86min 44sec (5204 seconds)
Published: Thu Apr 02 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.