Making a connection using the Lidgren networking library in Unity3d proved a bit more involved than I anticipated. My first challenge was to set up a proper multiplayer debug environment.
In a normal c# application you have full control of how you want to start your application. I like setting up two startup projects, one for the client and one for the server. This way I can do my client-server debugging in one environment and both the instances are launched at startup.
This proved to be a challenge in Unity. My first idea was to use a batch file to start two instances of unity with command-line arguments to distinguish between the client and the server. I found the custom command-line argument support to be lacking and didn’t pursue the idea any further.
I decided I would go the route of starting an instance of the game using the “Build & Run” command and then to start the second instance through the editor. To make this work you have to enable the “Run in Background” option under Edit –> Project Settings –> Player.
Without this setting enabled the non-focused instance would become unresponsive. I think Unity stops processing the Update methods when the window loses focus.
Next I needed some way to configure each instance as either the server or the client. I made use of a simple GUI with two buttons “Host Game” and “Join Game”. The nice thing about Unity is that is has GUI support out the box.
NOTE: I am not 100% comfortable with how to best structure a solution yet. I can see that the GUI stuff can become messy really fast.
Now I had enough to launch either a client or server instance. The next step was to get the Lidgren-network-gen3 library working in the Unity environment. I have included the steps I followed for reference below:
Step 1: Get the source code from the Google code repository.
Step 2: Open the solution in MonoDevelop. I used MonoDevelop rather than Visual Studio since the Assembly needs to be compiled for Mono.
Step 3: Follow the instructions from the wiki.
I thought this would be enough, but the Lidgren networking library was upgraded to .NET 4 and would not work in Unity.
The error message I got was MissingMethodException for ‘System.Threading.Monitor.Enter’. It would happen on my netPeer.Start() call.
After some googling I found the solution here.
Step 4: Set Lidgren project to build to .NET framework 3.5
Step 5: Remove reference to Microsoft.CSharp assembly.
Step 6: Rebuild the project.
Step 7: Copy the binaries into your Unity3d asset folder. (I put mine in a assets\lib folder).
Step 8: In Unity change the Player settings to use .NET 2 instead of the .NET 2 subset. (Edit –> Project Settings –> Player)
With that done I was ready to make the connection. Using the code from the XNA multiplayer article series. I copied across the INetworkingManager, ClientNetworkingManager and ServerNetworkingManager code.
When the user clicks on the “Host Game” button I instantiate the ServerNetworkingManager and when the user clicks the “Join Game” button I instantiate the ClientNetworkingManager.
In the FixedUpdate() method I make the call to ProcessNetworkingMessages()
In the above image you can see a screenshot of the server running in the Unity editor and the client running as a stand-alone instance.
For my next article I will cover getting the Asteroid synchronized across both instances.