Now, as you know this is really a XBox One Indie Development blog, how is this relevant? Well, as I am sure you know, if you are part of the ID@XBox program, then it has been announced that we will get an XB1 license for free for developing on the XB1 :D
So, I have embellished on this work in progress a little , and it now looks like this
As you can see, there are a few things we can go over, from the star field (it’s animated by the way, I know you can’t see that) to the ship trails as well as the main thread of this post, networking.
I am going to focus on the networking as I am going to put all the source up in a zip at the end for you to download, so you can have a look at how I have done it all, I dare say, Ill explain some of it as I go.
Caveat:-All that you read here is just how I found I could get it working, the only tutorials I have used have been for the basic network connection stuff, the rest is all my own work. So, with that being said, this may not be the best way to go about writing this in Unity 4.x, but it’s the way I have found (so far) I just hope that this gives those of you that have never done it before somewhere to start, and for those of you that this is all old hat for, please let me know how I can improve on it.
NetworkManagerThe first thing we are going to do is create a network manager to handle the setting up of the server and the connection’s between it and the client. I have written my network manager so that if there are no games being hosted, it will become the server, if there is 1, then it will attempt to connect. In a real game, I/we would create a lobby and have the option to either be a server or look for a server to join, but from this code I am sure you can figure out how easy that would be to do.
I went about creating my network manager by creating an empty GameObject in the scene, to that I had it host a GUIText GameObject like this:
I then added a C# script to the project and called it NetworkManager and added it to the empty GameObject.
NetworkManager.csThere is a far bit going on in here, lets have a look…
The PlayerPrefab is the prefab that will be used to instance the player(s) in the game, we will come to the creation of that in a little while, the MaxPlayers is where you can set the maximum number of players a server can host.
Lets get into these methods now:-
void Start()Like most MonoBehavior’s we have a Start method, in here we are going to set up the network.
void OnMasterServerEvent(MasterServerEvent msEvent)This method is provided by Unity, and is called as a response to MasterServer.RequestHostList, we can now decide if we need to connect to an existing game or create one of our own.
void OnServerInitialized()So, we have initialized the server, let the user know with SetStatus and spawn him/her a player to play the game with using SpawnPlayer and put them in the center of the game world.
void SetStatus(string status)This is my method to keep the user informed on what’s going on with the network, all it does it update the StatusText GUText text with what we want to show.
void OnPlayerConnected(NetworkPlayer player)A player has connected to the server, so, again, we inform the server player.
void OnConnectedToServer()This method is called by the client network after a successful Network.Connect, so in here we are going to tell the client player he has connected and create him/her a player to use.
public void SpawnClientPlayer(string name = null)This met5hod spawns a player, it differs as it will place the player at a random location and if it’s a re spawn, assign the new player with the current players name.
void OnDisconnectedFromServer(NetworkDisconnection info)This method is called by both client and server when they disconnect, it’s used here just to inform the user.
void OnFailedToConnect(NetworkConnectionError error)Again, another informative method should the connection fail.
void OnPlayerDisconnected(NetworkPlayer player)This method is called on the server when a player drops off, we inform the user then clear up the disconnected player. Using the provided NetworkPlayer object we need to find the player GameObject in the scene, then, if found destroy it, in this case we just inform the user with this method. We then clear our the players RPC and PlayerObjects over the network, this will remove it from all clients.
PlayerControler GetNetworkPlayerControler(NetworkPlayer player)This is a method of my own creation to get a player GameObject based on a given NetworkPlayer object.
void SpawnPlayer(Vector3 position, string name = null)This is my method to spawn a player GameObject in the scene. By using Network.Instantiate rather than Instantiate, we create the object on all the client machines too :) We then can set the players name and update it, both of these will be covered in the PlayerControler section.
public void UpdatePlayer(string id, string dispName, string text)This is my method to update a given player in the scene based on an ID, this again will be covered in the PlayerControler section as it is called from there.
public void DestroyPlayer(string id, string playerName)A method to update the network status to inform the user a player has been destroyed.
Player PrefabSo, we have a network manager, now we need a player to play the game with. I started off creating a Sprite GameObject in the scene, then, like with the Nework Manager gave it a child of GUText so it’s stats can be displayed. I then created a C# script called PlayerControler and attached this to the Sprite as well as giving it a RigidBody2D, a TrailRenderer a NewtorkView (most important) and a PollygonCollider2D. I then made this a prefab by dragging it into my Prefabs folder and deleted the one in the scene.
PlayerControler.csI guess this is where all the gameplay and gameplay networking sits, and to be honest, there is not a lot as the NetworkView does most of it for me. Here is the class in full, we can then take a look at what is going on here.
void Awake()In here, we check if this is running as the players instance or another players instance, this is done by looking at the networkview and it’s flag isMine, if it is we set the camera so it is looking at this game object, we don’t want to be looking at other players do we…
public void Shoot()This method is used to create bullets and shoot them, two per shot.
void OnTriggerEnter2D(Collider2D collider)This is our trigger, if we get hit by a bullet we deal with it as we need to, taking damage, increasing the shooters score and if we die, instantiate a sound effect, re spawn and remove us from the scene.
N.B need to change the re spawn code to re connect rather than just try and add a new player object.
void Update()In here we have the player controls, note, you really should not write them like this, use the Unity configurable keys, not like this :S Note the use of networkView.isMine so we only move our player not all in the scene. Also, I keep the text for the player bound to it by using
GetComponentInChildren<GUIText>().transform.position = Camera.main.WorldToViewportPoint(transform.position + (Vector3.down * 1));
Also notice, I don’t have to send anything down the network, the transform is sent by the networkView :)
public void UpdateNetworkPlayer()This method is the only one that does ANY network calls, and all it is doing is calling the UpdatePlayer RPC method I have set up in the PlayerControler which we will look at next.
I could have gone with OthersBuffered, but I wanted to have the code to update the status in one place and this lets me do this or I would have to make a second call to update myself as well as the other players on the network.
void UpdatePlayer(string id, string playerName, string status)And so we come to the actual RPC call it’s self, again keeping the code in one place I decided the best place to put this was in the network manager code, so I pass on all the prams to it’s method and it goes through all the players in the scene and if it finds a matching ID, updates them.
void OnGUI()And here is where I set up the GUI, so a field for you to enter your player name and also show all the known players and their stats that are currently in play.
Now, naturally there are things in here I want to change, but, it works, well enough for a start and I would have never gotten around to writing this post if I kept adding stuff so forgive me if this post does not go far enough for you.
As ever, all comments and criticisms are welcome, all you have to do is post them.
If you want to get all the source for this you can find it all in a zip file here.
If you want to play the game as it currently stands then have a look here.