Adam O'Grady

Multiplayer FPS In Unity

I’ve done a fair bit of Unity3D work before, but it’s mostly been “fun” projects or random stuff to test out hardware like the Leap Motion. But recently a friend has invited me to join his small collective that are working towards building a video game. It’s mostly a hobby-with-direction and since we all have our own lives as well it may not go far or reach it’s goal quickly; but that doesn’t stop us having fun and trying new things. To test my skills, I was tasked with building a small, 1v1 FPS. It could use prefabs and be as simple as possible, but it just needed the multiplayer component and FPS viewpoint component.

I managed to get the project ready over the course of a day and wanted to point out a number of “gotchas” that exist when building multiplayer games:

  • Create a network manager script Attach said script to an empty GameObject or an unused object in the scene. Add the following MonoBehaviour functions which instantiate an object that has been created as a public variable (and so can be assigned a prefab in the Unity editor). This will create a player object when the host starts up and when a player connects.

    public GameObject playerPrefab;

    void OnConnectedToServer() { Network.Instantiate(playerPrefab, new Vector3(0, 0, 0), Quaternion.identity, 0); }

    void OnServerInitialized() { Network.Instantiate(playerPrefab, new Vector3(0, 0, 0), Quaternion.identity, 0); }

  • Set a host/client mechanism Find some way of deciding who is host and who is a client that joins the hosts’ game. This can probably be done a few different ways, both in the existing scene by having particular key-presses or clicks of a GUI.Button or in a previous scene which passes data to the game screen about each instances role.

  • Each player controls only their avatar Best way to do this is to put any movement, jumping, firing code inside the following code block. This makes sure that players only control the object which belongs to them as per the NetworkView component on it.

    if (networkView.isMine) { //code }

  • For FPS: lock camera to user This one got me for a bit. When you’re players are acting in an FPS game style, you’ll need to attach a script to the object which contains their camera and put the code below inside it. This means they’ll be using their own camera and not accidentally looking out of an opponents.

    void Awake() { if (networkView.isMine) { camera.enabled = true; } else { camera.enabled = false; } }

  • Separate horizontal and vertical view components One of the problems I’ve noticed when building an FPS viewpoint is if you have a camera component connected directly to the main player and it has both X and Y rotation, it can get weirdly stuck on an angle. The best way I found to stop that is to put the camera on a second, invisible GameObject inside and parented by the player GameObject (at head height). Give horizontal movement to the player object and vertical look to the camera and it should fix that up.