Multiplayer with Unity and SmartFox tutorial

Introduction
This tutorial will show you how to create a simple level in Unity with SmartFox multiplayer support. It will use a third person view (as opposed to the first person view in the SmartFox Island demo). I have changed a some of the Island Demo settings (different zone and room for example) so you know what to change where.

I am by no means an expert in Unity or SmartFox, so if things can be done better or more efficient, please add and edit!

Install SmartFoxServer
             
 * First install SmartFoxServer PRO (make sure it is the PRO version)
 * You can use the pro version for free with up to 20 connections, more than enough for this tutorial.
 * If you're installing on Windows 7, then you need to have "Run as Administrator" ticked for java.exe (directory C:\Program Files (x86)\SmartFoxServerPRO_1.6.6\jre\bin)
 * At the time of writing (November 5, 2010), version 1.6.6 is the latest stable. Pretty soon SFS2X should come out of beta, check the SmartFox Forums for details.
 * Configure a new Zone that we will use for this tutorial, by adding the following in the  section of the config.xml file (Server directory):
 * Start the server (in Windows using the Start Menu shortcuts, in Linux using the sfs script in the Server directory: ./sfs restart).
 * If you want to autostart the SmartFox Server under linux, add it to the startup sequence (with Ubuntu: copy/symlink the sfs script to /etc/init.d and run sudo update-rc.d sfs defaults )

Create the scene in Unity

 * Create a new Unity project and select to import the Character Controller .unityPackage
 * You can always import more packages later, for now we only need this one.


 * For this tutorial we will create a simple box to walk around in:
 * Create a cube (GameObject > Create Other > Cube), in the Inspector set position to 0,0,0 and scale to 25,1,25. Rename it floor.
 * Create another cube, set position to 0,5,12 and scale to 25,10,1, rename it wall_1.
 * Copy wall_1, set position to 0,5,-12 and rename it wall_2.
 * Copy wall_1, set position to 12,5,0 and the rotation Y to 90. Rename it wall_3.
 * Copy wall_3, set position to -12,5,0 and rename it wall_4.
 * Add a directional light (GameObject > Create Other > Directional Light) and aim it in the box by rotating it.
 * It does not matter where you position a directional light in the scene, only the angle is important.


 * Add the 3rd Person Controller to the scene (position 0, 1.5, 0 places him in the center) and rename to localPlayer.
 * Save the scene as sc_City (I usually create a subfolder Scenes where I put the scenes) and add it to the Build Settings (ctrl-shift-b).

Add SmartFox to the Unity project

 * Download the SmartFox .Net API from the SmartFox API page.
 * In the Unity project folder, create a new folder Plugins in the Assets directory.
 * Copy the SmartFoxClient.dll from the API/binaries directory in the zipfile to Plugins folder.

Create the login page

 * Create a new scene in Unity, save it as sc_Login and add it to the Build Settings.
 * Create a new folder Scripts and in there create a new C# script, rename it gui_Login and copy the contents from the page BOX1 - gui_Login.cs script.
 * Create a new C# script, rename it SmartFox and copy the contents from the page BOX1 - SmartFox.cs script.
 * Create an empty GameObject, rename it to gui_Login, and attach the gui_Login script.
 * Save the scene and project and try running it. You should get a login page, after login the scene with the box is loaded.

Getting the components in place

 * We'll be using the network scripts that are provided with the SmartFox Island Demo, get the demo project here.
 * Copy the network folder with scripts from the demo to our scripts folder.
 * Copy the script Assets/Scripts/FPSStorage.cs and Assets/Scripts/FPSCounter.js from the demo to our scripts folder.
 * Add an empty game object in the scene, rename it to " FPS" (with a space), attach both FPS scripts and add a GUIText component (Component > Rendering > GUIText).
 * Edit the NetworkController script from the island demo:
 * Change Application.LoadLevel("login"); to Application.LoadLevel("sc_Login");
 * Change smartFoxClient.JoinRoom("The Garden"); to smartFoxClient.JoinRoom("Central Square");

Configuring local & remote player

 * Add the script NetworkTransformSender and AnimationSynchronizer to localPlayer. This will broadcast the position whenever the player moves so that other clients can update the position of this player.
 * Create a new folder Network Assets in the Project view, in that folder create a new prefab and rename it to "remotePlayer".
 * In the Project view, drag the 3rd Person Controller (in Standard Assets > Character Controllers) onto the remotePlayer prefab.
 * Select the remotePlayer and remove the Third Person Camera, Third Person Controller and Character Controller.
 * Select the remotePlayer and add the scripts NetworkTransformReceiver and AnimationSynchronizer.

The network & spawn controller

 * Create an empty object, rename it to NetworkController and add the NetworkController script and the PlayerSpawnController script.
 * The NetworkController script updates movement of the other players and registers other SmartFox events (such as a player leaving or entering).


 * Select the NetworkController object and link the localPlayer from the Hierarchy to the Local Player Object field in the Inspector.
 * Select the NetworkController object and link the remotePlayer from the 'Project view' to the Remote Player Prefab field in the Inspector.
 * We do not need to create a remotePlayer object in the scene, because that is done dynamically when other players join. Therefore we link the prefab so the script knows what to instantiate.


 * Create 4 empty objects, place them in the box, rename to SpawnpointA - SpawnpointD and link to the NetworkController object (first set Size to 4 under Spawn Points).

Adding animation to remote players

 * To get the remote players to actually walk (instead of floating around), we need to add sendmessage commands to the Third Person Controller script. This networkcontroller monitors for these messages and upon receiving them will trigger the animation in the remote player object.
 * Edit ThirdPersonController.js in Assets\Standard Assets\Character Controllers\Sources\Scripts and replace the //ANIMATION sector part with the lines below (with added the sendmessage lines):

Adding a in-game GUI with status window and chat

 * Load the sc_City scene.
 * For the chat, we will be using the scripts and skin that come with the Island Demo.
 * Copy the skin folder with gui files from the demo to our assets folder
 * Link the ChatController to the NetworkController by dragging the script from the Project view on the NetworkController object in the Hierarchy view.
 * Link the skin script to the ChatController that is attached to the NetworkController by dragging the skin script from the Skin folder in the Project view on the Skin field in the ChatController section of the NetworkController object (in the Hierarchy view).
 * Create a new C# script, rename it gui_Game and copy the contents from the page BOX1 - gui_Game.cs script.
 * Add some changes to the NetworkController.cs script to update the Status Window when players enter or leave.
 * The windows is updated through the UpdateStatusMessage function in gui_Game.cs, therefore we add:
 * Complete code for adapted NetworkController.cs is here: BOX1 - NetworkController.cs script.


 * To be able to access the functions, link the gui_Game script to the NetworkController by dragging the script from the Project view on the NetworkController object in the Hierarchy view.