step3b_spawnplayers-1024x558

How to create an online multiplayer game with Unity

September 6, 2016: We are looking for a Unity C# Developer and Node.js/Back-end Developer to join our team. You can find the vacancies here!

This tutorial will explain how multiplayer can be implemented using Unity’s networking functionality. We didn’t work on an online multiplayer game before, and here will we describe how we designed the implementation for LFG: The Fork of Truth. This is a four person co-op game where each player controls one of the characters from the LFG comic. Players will be working together by combining their abilities to defeat their enemies and complete quests.

In this tutorial I explain how to create a online multiplayer game using Photon Unity Networking (PUN), instead of the standard Unity networking.

The video below is from the Kickstarter-demo we have made and shows the gameplay and multiplayer functionality which we are going to talk about.

An important decision we made at the start of the project was to implement networking first and all other code later. For each new feature we made sure it worked over the network. In the end this saved us a lot of time, because implementing it at a later stage would probably result in changing a lot of code. To follow this tutorial, a basic understanding of Unity and C# is required.

These are the things we are going to talk about:

  1. Implement server creation and joining an existing host.
  2. Spawning as a player and how objects can be created on the network.
  3. Network communication using State Synchronization and Remote Procedure Calls.
  4. Interpolating and predicting values between data packages.

Networking was a new topic for us and I found this video tutorial very useful to start with. It’s explained in Javascript, but covers the same content as the first three paragraphs.

Creating a server

So let’s get started! In the new Unity project, create a new C# script named “NetworkManager”. Add this empty script to an object in the scene, either the camera or an empty game object. It will handle hosting a server or connecting to an existing server.

To create a server, we need to initialize it on the network and register it to the master server. The initialization requires a maximum amount of players (in this case 4) and a port number (25000). For the server registration the name of the game should be unique, otherwise you might get in trouble with others projects using the same name. The room name can be any name, and in our case we eventually used the player name. Add these lines to the NetworkManager script.

private const string typeName = "UniqueGameName";
private const string gameName = "RoomName";

private void StartServer()
{
    Network.InitializeServer(4, 25000, !Network.HavePublicAddress());
    MasterServer.RegisterHost(typeName, gameName);
}

If the server is successfully initialized, OnServerInitialized() will be called. For now, we are happy to get feedback telling us the server is actually initialized.

void OnServerInitialized()
{
    Debug.Log("Server Initializied");
}

All we need now is some form of input to let us actually start the server when we want to. To test it out we create buttons using the Unity GUI. We only want to see these buttons if we have not started a server or joined one, so the button will show itself if the user is neither a client nor a server.

void OnGUI()
{
    if (!Network.isClient && !Network.isServer)
    {
        if (GUI.Button(new Rect(100, 100, 250, 100), "Start Server"))
            StartServer();
    }
}

Now it is time to test what we developed so far. When starting the project, all you should see now is a start server button (1A) . If you press this button, a message should be shown in the console indicating you just initialized a server. Afterwards the button should disappear (1B).

This MasterServer is run by Unity and could be down due to maintenance. You can download and run your own MasterServer locally. Add to NetworkManager.cs the following:

MasterServer.ipAddress = “127.0.0.1″;

Thanks to jeff77k for this addition!

Joining a server

We now have the functionality to create a server, but can not yet search for existing servers or join one of them. To achieve this, we need to send a request to the master server to get a list of HostData. This contains all data required to join a server. Once the host list is received, a message is sent to the game which triggers OnMasterServerEvent(). This function is called for several events, so we need to add a check to see if the message equals MasterServerEvent.HostListReceived. If this is the case, we can store the host list.

private HostData[] hostList;

private void RefreshHostList()
{
    MasterServer.RequestHostList(typeName);
}

void OnMasterServerEvent(MasterServerEvent msEvent)
{
    if (msEvent == MasterServerEvent.HostListReceived)
        hostList = MasterServer.PollHostList();
}

To join a server, all we need is one entry of the host list. The OnConnectedToServer() is called after we actually joined the server. We will extend this function at a later point.

private void JoinServer(HostData hostData)
{
    Network.Connect(hostData);
}

void OnConnectedToServer()
{
    Debug.Log("Server Joined");
}

By extending the GUI with some additional buttons, the functions we just created can be called. There will be two buttons now at the start, one to start the server and another to refresh the host list. A new button is created for every server and it will connect the user to the corresponding room.

void OnGUI()
{
    if (!Network.isClient && !Network.isServer)
    {
        if (GUI.Button(new Rect(100, 100, 250, 100), "Start Server"))
            StartServer();

        if (GUI.Button(new Rect(100, 250, 250, 100), "Refresh Hosts"))
            RefreshHostList();

        if (hostList != null)
        {
            for (int i = 0; i < hostList.Length; i++)
            {
                if (GUI.Button(new Rect(400, 100 + (110 * i), 300, 100), hostList[i].gameName))
                    JoinServer(hostList[i]);
            }
        }
    }
}

This is a good point to do another test (2A). One thing to note is that testing multiplayer takes a bit longer, particularly because you always require two instances of the game. To run two instances on the same computer this settings needs to be checked. Go to File > Build Settings > Player Settings > Run in Background and enable it. Now create a new build, launch it and press “Start Server”. Now we can test our new functionality in the Unity editor. After refreshing your list, another button should appear (2B) allowing you to connect the two instances of your game (2C).

Spawning a player

Now we should be able to connect multiple players to one another, we can now extend the code with game mechanics. Set up a simple scene with a floor plane, player and some lighting. Add a rigidbody to the player and freeze the rotations, so we will not get strange behaviour while moving.

Scene Setup

Create a Player-script, add it to the player object and add the following code:

public class Player : MonoBehaviour
{
    public float speed = 10f;

    void Update()
    {
        InputMovement();
    }

    void InputMovement()
    {
        if (Input.GetKey(KeyCode.W))
            rigidbody.MovePosition(rigidbody.position + Vector3.forward * speed * Time.deltaTime);

        if (Input.GetKey(KeyCode.S))
            rigidbody.MovePosition(rigidbody.position - Vector3.forward * speed * Time.deltaTime);

        if (Input.GetKey(KeyCode.D))
            rigidbody.MovePosition(rigidbody.position + Vector3.right * speed * Time.deltaTime);

        if (Input.GetKey(KeyCode.A))
            rigidbody.MovePosition(rigidbody.position - Vector3.right * speed * Time.deltaTime);
    }
}

Next, add the network view component to the player object (Component > Miscellaneous > Network View). This will enable us to send data packages over the network to synchronize the player. The state synchronization field is automatically set to “reliable delta compressed”. This means that synchronized data will be sent automatically, but only if its value changed. So for example if you move as a player, your position will be updated on the server. By setting it to “off” there is no automatic synchronization at all and you have to do it manually. For now set it to “reliable”, later in this tutorial these options will be discussed in more detail. Add the player object to the hierarchy to make it a prefab, so we can instantiate it on the network.

In the NetworkManager-script add a public game object variable for the player prefab. In the new function SpawnPlayer(), the prefab will be instantiated on the network, so all clients will see this object within their game. It requires a position, rotation and group, so I would suggest creating a spawn point.

The code in OnServerInitialized() and OnConnectedToServer() needs to be changed to spawn the player.

public GameObject playerPrefab;

void OnServerInitialized()
{
    SpawnPlayer();
}

void OnConnectedToServer()
{
    SpawnPlayer();
}

private void SpawnPlayer()
{
    Network.Instantiate(playerPrefab, new Vector3(0f, 5f, 0f), Quaternion.identity, 0);
}

Time for another test! Create a new build and run two instances again. You will notice that you can control all players connected, not just your own. This shows one important aspect that will be used often when creating a multiplayer game: who controls what object?

Spawning Players

One way to fix this problem is to build in a check on the player code so it only receives input from the user that instantiated the object. Because we set reliable synchronization on the network view, data is sent automatically across the network and no other information is required.

To implement this method, we need to check whether the object on the network “is mine” in the player script. Add the following if-statement to the Update():

void Update()
{
    if (networkView.isMine)
    {
        InputMovement();
    }
}

If you do another test now, you will see you can only control one of the players.

Another solution could be to send all input to the server, which will then convert your data to actual movement and send back your new position to everyone on the network. The advantage is that everything is synchronized on the server. This prevents players from cheating on their local client. A disadvantage of this method is the latency between the client and server, which may result in the user having to wait to see the actions he performed.

State Synchronization

There are two methods of network communication. The first is State Synchronization and the other is Remote Procedure Calls, which will be covered in another paragraph. State Synchronization constantly updates values over the network. This approach is useful for data that changes often, like player movement. In the function OnSerializeNetworkView() the variables are sent or received and will synchronize them quick and simple. To show you how this works, we will write the code that synchronizes the player’s position.

Go to the network view component on the player’s prefab. The observed field contains the component that will be synchronized. The transform is automatically added to this field, which results in the position, rotation and scale being updated depending on the sendrate. Drag the component of the player script in the observed field so we can write our own synchronization method.

Add OnSerializeNetworkView() to the player script. This function is automatically called every time it either sends or receives data. If the user is writing to the stream, it means he is sending the data. By using stream.Serialize() the variable will be serialized and received by other clients. If the user receives the data, the same serialization-function is called and can now be set to store the data locally. Note that the order of variables should be the same for sending and receiving data, otherwise the values will be mixed up.

void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
{
    Vector3 syncPosition = Vector3.zero;
    if (stream.isWriting)
    {
        syncPosition = rigidbody.position;
        stream.Serialize(ref syncPosition);
    }
    else
    {
        stream.Serialize(ref syncPosition);
        rigidbody.position = syncPosition;
    }
}

Make another build and run it. The results should be the same as before, but now we have granted ourselves control over the movement and how the synchronization works.

Interpolation

You might have noticed latency issues between the two instances due to the sendrate. The standard settings in Unity is that a package is being tried to send 15 times per second. For testing purposes, we will change the sendrate. To do this, first go to the network settings at (Edit> Project Settings > Network). Then, change the sendrate to 5, resulting is less data packages being sent. If you would do another build and test, the latency should be clearer.

To smooth the transition from the old to the new data values and fix these latency issues, interpolation can be used. There are several options how this can be implemented. For this tutorial, we will interpolate between the current position and the new position received after synchronization.

OnSerializeNetworkView() needs to be extended with to store all the required data: the current position, new position and delay between updates.

private float lastSynchronizationTime = 0f;
private float syncDelay = 0f;
private float syncTime = 0f;
private Vector3 syncStartPosition = Vector3.zero;
private Vector3 syncEndPosition = Vector3.zero;

void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
{
    Vector3 syncPosition = Vector3.zero;
    if (stream.isWriting)
    {
        syncPosition = rigidbody.position;
        stream.Serialize(ref syncPosition);
    }
    else
    {
        stream.Serialize(ref syncPosition);

        syncTime = 0f;
        syncDelay = Time.time - lastSynchronizationTime;
        lastSynchronizationTime = Time.time;

        syncStartPosition = rigidbody.position;
        syncEndPosition = syncPosition;
    }
}

We had a check in Update() whether the object is controlled by the player. We need to add the functionality that when this is not the case, we will use interpolation between the synchronized values.

void Update()
{
    if (networkView.isMine)
    {
        InputMovement();
    }
    else
    {
        SyncedMovement();
    }
}

private void SyncedMovement()
{
    syncTime += Time.deltaTime;
    rigidbody.position = Vector3.Lerp(syncStartPosition, syncEndPosition, syncTime / syncDelay);
}

Create a new build and test it, you should now see the transition looks better between updates.

Prediction

Though the transitions look smooth, you notice a small delay between the input and the actual movement. This is because the position is updated after the new data is received. Until we invent time travel, all we can do is predict what is going to happen based on the old data.

One method to predict the next position is by taking the velocity into account. A more accurate end position can be calculated by adding the velocity multiplied by the delay.

void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
{
    Vector3 syncPosition = Vector3.zero;
    Vector3 syncVelocity = Vector3.zero;
    if (stream.isWriting)
    {
        syncPosition = rigidbody.position;
        stream.Serialize(ref syncPosition);

        syncVelocity = rigidbody.velocity;
        stream.Serialize(ref syncVelocity);
    }
    else
    {
        stream.Serialize(ref syncPosition);
        stream.Serialize(ref syncVelocity);

        syncTime = 0f;
        syncDelay = Time.time - lastSynchronizationTime;
        lastSynchronizationTime = Time.time;

        syncEndPosition = syncPosition + syncVelocity * syncDelay;
        syncStartPosition = rigidbody.position;
    }
}

After building and testing the game again, you will notice the transitions are still smooth and the latency between your input and the actual movement seem less. There are also a few corner-cases where behaviour might seem a little strange if the latency is too high. If the player starts moving, the other clients still predict you would stand still. Set the sendrate at network settings back to 15 updates per second for better results.

For our Kickstarter demo, we used a navmesh to walk around and this seemed to make interpolation and prediction better. The sendrate was set to 5 and as a user you could barely notice the delay. This tutorial will not go any deeper into the integration of the navmesh, but for your future projects it might be worth to consider this approach.

Remote Procedure Calls

Another method of network communication is Remote Procedure Calls (RPCs), which is more useful for data that does not constantly change. A good example what we used these for in our Kickstarter demo is dialog. In this paragraph we will change the color of a player over the network.

What RPCs do is a function call on a network view component and this component searches the correct RPC function. By adding [RPC] in front of the function, it can be called over the network. This approach is only able to send integers, floats, strings, networkViewIDs, vectors and quaternions. So not all parameters can be sent, but this can be solved. To send a game object, we should add a network view component to this object so we can use its networkViewID. To send a color, we should convert it to a vector or quaternion.

An RPC is sent by calling networkView.RPC(), in which you define the function name and parameters. Also the RPC mode is required: “Server” sends the data to the server only, “Others” to everyone on the server except yourself and “All” sends it to everyone. The last two also have the functionality to set is as buffered, this results in newly connected players receiving all these buffered values. Because we send this data package every frame now, there is no need to buffer it.

To integrate this functionality to our tutorial game, Update() needs to call the function to check for input and change the material to a random color. The RPC function changes the color based on the input and if the player object is controlled by the user, he will send an RPC to all others on the network.

void Update()
{
    if (networkView.isMine)
    {
        InputMovement();
        InputColorChange();
    }
    else
    {
        SyncedMovement();
    }
}

private void InputColorChange()
{
    if (Input.GetKeyDown(KeyCode.R))
        ChangeColorTo(new Vector3(Random.Range(0f, 1f), Random.Range(0f, 1f), Random.Range(0f, 1f)));
}

[RPC] void ChangeColorTo(Vector3 color)
{
    renderer.material.color = new Color(color.x, color.y, color.z, 1f);

    if (networkView.isMine)
        networkView.RPC("ChangeColorTo", RPCMode.OthersBuffered, color);
}

Now create another build and if you run the game, you will see the player’s colors can be changed.

Changing Color

Conclusion

I hope this tutorial was a good introduction to implement networking to a Unity game. The subjects we have addressed are:

  • How to create and join a server
  • How to find active hosts
  • Player or object creation over the network
  • Methods of implementing network communication
  • How to interpolate and predict synchronized data

You can download the entire project here.

As you might have noticed there are a lot of choices that need to be made along the way, depending on the game’s requirements. This tutorial briefly explained our implementation for the Kickstarter demo of LFG: The Fork of Truth.

If you have any questions, suggestions or comments, feel free to use the comment section below.

156 Comments
  • mikehergaarden
    Posted at 14:47h, 10 July Reply

    Houden jullie vast aan UnityNetworking voor de game? Je krijgt veel problemen met spelers die niet met elkaar kunnen verbinden. Als alternatief kan je bijvoorbeeld gemakkelijk overstappen naar PUN (Photon Unity Networking). Zelfde API maar krachtiger + via de cloud.

    • Stein Damen
      Posted at 14:53h, 10 July Reply

      Hoi Mike, bedankt voor je suggestie. Dat gaan we nog zeker onderzoeken. Voor nu hebben we gekozen voor UnityNetworking vanwege de kleine schaal van de demo.

      • mikehergaarden
        Posted at 15:01h, 10 July Reply

        Ok cool, makes sense. Ik heb de Unity networking guide geschreven een paar jaar terug en daarna PUN ontwikkeld voor Unity+ExitGames, dus mochten er ooit nog vragen komen kan ik wel wat pointers geven.

    • addd
      Posted at 23:16h, 31 July Reply

      it is a awesome solution with floating origin but how do you create it? i dont find the information :/
      http://answers.unity3d.com/questions/754247/z-fighting-issue-how-to-fix-pc-1.html

    • Willy Campos
      Posted at 18:44h, 24 October Reply

      Hey, this is a great example and tutorial on how to start with multiplayer games, since it covers most of the basic things needed to understand a networked game. Using state Sync is great for small projects that do not require a high amount of messages constantly being sent/received, using entirely RPCs will help you achieve a more controlled and efficient communication and process environment. Yes having such things as a much more efficient system comes with the cost of having to code more things, and while all this can be a class that is very easily maintainable it is well worth the effort. Not only will you be able to run more instances of your games on the same hardware and will be less taxing on processing power and bandwidth usage. Which, if you want to host your servers on the cloud, can reduce a lot of costs and make all your infrastructure smaller and less complicated. Another thing that can help in the same way is to specialize your code by separating the server exclusive code from the client’s code. Not only will this help in performance but will make most changes very easy to maintain and update to production since you control the server hosts.
      I would like to redirect users from my blog who want to start making a multiplayer game to this guide if you don’t mind, I find it concise, and useful for the basics of networking in games. Btw, if you would like to check many more optimizations on multiplayer games, you can check my blog.

  • Grim
    Posted at 15:56h, 10 July Reply

    Interesting read.

  • Nathan van Hulst
    Posted at 17:25h, 10 July Reply

    Very nice Tutorial. However for all other people trying this tutorial. There is one thing that has been forgotten once you try to run a server and client on the same computer. When publishing, turn on at publish settings: “Run in Background” Else you won’t be able to connect to the server, unless you focus on the game instance running the server after client has been connected. Took me few minutes to find that issue 😉

    • Jens
      Posted at 19:56h, 10 July Reply

      Thanks for pointing that out, I’ll add it tomorrow 🙂

    • Nathan
      Posted at 09:40h, 05 September Reply

      i selected this option, ‘Run in Background’, under ‘Player Settings’ but it didn’t seem to change anything. Any idea why?

      • Jens van de Water
        Posted at 09:04h, 04 October Reply

        I’m sorry, I don’t know what might cause this problem. Are you sure the setting is saved in the project? It might be best to go to the Unity forums and report it there. Good luck!

    • NitroFingers
      Posted at 20:57h, 26 May Reply

      THANK YOU SO MUCH!

    • waldi
      Posted at 01:10h, 03 June Reply

      oh my god!!! took me an hour to finally read your comment. thank you so much this helped. got confused because the donwload of the entire project worked on one pc!?
      File->Build Settings…->Player Settings…-> (Check) Run in Background*
      🙂

      • Jens
        Posted at 09:42h, 14 July Reply

        I added it to the tutorial, hope this will help future readers 🙂

  • dhruv chopra
    Posted at 14:45h, 11 July Reply

    Hi Stein – I would like you to also explore AppWarp Cloud Unity SDK. It allows developers to connect to AppWarp cloud server and has ready made APIs for rooms/lobby/chat/update/matchmaking etc.

    http://blogs.shephertz.com/2013/04/30/make-real-time-multiplayer-games-using-unity3d/

    • Stein Damen
      Posted at 15:20h, 11 July Reply

      Hi Dhruv. Thanks for the suggestion! Will keep it in mind.

    • Scott
      Posted at 22:13h, 08 January Reply

      Has anyone on here actually used this method? Because the listener code doesn’t work for me it says ‘MoveEvent does not exist’. Anyone know how to fix this?

  • Bryan Keiren
    Posted at 15:11h, 13 July Reply

    Heya guys, just a suggestion: You don’t need to manually check to see whether the host list has been received in Update() every frame. Unity provides the OnMasterServerEvent() function for MonoBehaviours, which will be called for a number of events, including receiving the host list from the master server (http://docs.unity3d.com/Documentation/ScriptReference/MonoBehaviour.OnMasterServerEvent.html). Simply check the one argument that is received by that event to see if it equals MasterServerEvent.HostListReceived and you’ll know exactly when it has arrived.

    That way you also don’t need to build any custom time out timer or anything (because in your current code ‘isRefreshingHostList’ would never return to being false if there are 0 hosts.

    Nice write-up though, and good to see another Dutch studio working on a promising project!

  • owenoliver1
    Posted at 15:19h, 20 July Reply

    I am having an issue with this tutorial. I am going through and get up to the part where I connect two players to each other and the problem I am having is that the position isn’t updating and on the client the player always look to be under the floor and flashing when they do move to the position they are in.
    I have worked out that it is because the observed network view is set to the player position whereas in the downloaded example file it is set to a C# script how do I fix this?

    • Jens van de Water
      Posted at 09:23h, 29 July Reply

      If you’re at the stage of “spawning a player”, the player’s transform should be in the observed field. This is set automatically and does not require code to update the position.

      For “state synchronization” the script needs to be added to the network view’s observed field. To do this, first add the C# script to the player object, so the component appears in the inspector. Now you are able to drag this component into the observed-field (overwriting the transform).

      • trynyty
        Posted at 02:49h, 30 August Reply

        Yes, that’s it… I would suggest to put in the BOLD that you have to drag the component from the object not the script from the project 🙂 which was my case, and I wasn’t able to understand what’s wrong with it … 😉

        • Marcelo de Freitas Rigon
          Posted at 19:32h, 12 February Reply

          I was struggling with the same thing here. Thanks for pointing it out. 😀

  • David Gibson
    Posted at 04:13h, 07 August Reply

    This tutorial is exactly what I’ve been looking for to get my feet under me with netcode. Thanks for writing it! One thing that tripped me up and might be useful to clarify; I’d assumed in the seralization section that you were in essence ‘asking’ the stream for a variable with a given name in the deserialization portion, so I didn’t catch on that it’s order, not name, that’s important. I spent a while trying to debug things before realizing that the clients were getting position and velocity swapped for things they don’t own. Explaining what’s going on there in more detail might be useful to people.

    • Jens van de Water
      Posted at 10:06h, 07 August Reply

      Great to hear this post was able to help you. Sorry for not adding the importance of ordering variables during synchronization. I’ve added it to the post to avoid problems in the future. Thanks!

  • Justin Sargent (@theJusarg)
    Posted at 01:37h, 09 August Reply

    This couldn’t have come at a better time, I just started learning Unity Networking and found this post while searching how to run two copies of my game (to test multiplayer).

    Thanks for the great tutorial and too bad your kickstarter didn’t get funded =[

  • Zippyllama
    Posted at 08:30h, 13 August Reply

    Extremely useful! Thanks guys

  • ankur
    Posted at 14:46h, 23 August Reply

    how can i fetch the list of players connected to my server

    • Jens van de Water
      Posted at 08:35h, 30 August Reply

      Network.connections returns an array of connected players.

  • Maddy
    Posted at 08:29h, 30 August Reply

    The project is empty you gave in to the link “You can download the entire project here.” Can you upload it?

    • Stein Damen
      Posted at 10:28h, 04 September Reply

      Hi Maddy, the download works for me. Maybe you can try again with another web browser or something.

  • Nathan
    Posted at 08:46h, 05 September Reply

    Hey nice tutorial, although i am having an issue with connecting both instances to the server. From within the build i can connect, but when i try to connect within the unity editor i get an error stating “Its not possible to register a host until it is running.” Help would be great 🙂

    • Fafase
      Posted at 12:51h, 15 January Reply

      I get the same. Despite a copy paste of the OnGUI. Still trying.

  • Ahmet
    Posted at 17:30h, 24 September Reply

    Hello jens,would youike to make an online multiplayer game with me and a few other people please contact me at my e-mail: ahmetcelaltopra@gmail.com

  • Ãkžäm Łøxš
    Posted at 16:09h, 02 October Reply

    weres the video??????????

  • Emilio Estrada
    Posted at 06:35h, 04 October Reply

    Amazing tutorial…
    What I am going to do in two weeks (when I get paid) is buying at least one of your games… You help me, I help you… Keep’em coming.

  • José Francisco Junior
    Posted at 08:45h, 08 October Reply

    Very nice tutorial!!! Thank you for sharing your knowledge and good luck for you guys…

  • Francis Humphries
    Posted at 18:40h, 09 October Reply

    This was really helpful for me- I learned how easy networking actually is! Thanks for the tips. By the way, I also converted all the scripts here to JavaScript, so if you’d like a JS version of both scripts I can provide such.

    • Stein Damen
      Posted at 12:00h, 14 October Reply

      Hi Francis. That would be a great extension to the post. We could add a link to download the project in JS if you’d like. Contact me at stein@paladinstudios.com if you want to discuss it further.

  • memoi
    Posted at 13:56h, 13 October Reply

    In case people are like me (did not learn the basics) and stumble upon the error “Player must be a prefab in the project view”.

    – Drag the cube (Player) from Hierarchy in Assets.
    – Delete the cube from the scene.
    – In hierarchy select the Game Object where your Network Manager Script is attached.
    – Drag the cube (Player) from Assets to the playerPrefab variable in the Inspector.

    Hope this helps

  • memoi
    Posted at 21:57h, 13 October Reply

    There is a typo error at Prediction line 10.
    syncPosition = rigidbody.velocity;
    should be
    syncVelocity = rigidbody.velocity;

  • Stein Damen
    Posted at 11:41h, 14 October Reply

    Thanks for the feedback Memoi. Typo is fixed.

    • reaganr
      Posted at 20:49h, 21 March Reply

      fyi, this typo is still in the source file.. makes the 3rd instance fly off the screen..

  • Bryan
    Posted at 16:46h, 14 October Reply

    Um, my player jumps around crazily 🙁 it jumps to Vector3.zero, then back and I’m cracking my head over this >:(

    • Daniel S
      Posted at 22:44h, 22 October Reply

      hmm yes… i have the same problem 🙁 checked my code again but couldn’t find any mistake :-/

      any ideas? Thanks !

    • Daniel S
      Posted at 22:58h, 23 October Reply

      DAMN !! -.- ok i fixed it ! you should have mentioned that we have to drop the “player” script COMPONENT into the OBSERVED slot of the Network view -.-‘
      When i followed this tutorial the standard value of the observed slot where “Player(Transform)” .. this does NOT work for me -.-‘

      • Dan
        Posted at 21:33h, 04 November Reply

        Maybe you should start with a TicTac game tutorial?

        • Max Munro
          Posted at 09:09h, 28 March Reply

          It’s not exactly standard procedure so drag an inspector script into a slot on its own gameobject in that way. Normally these slots are pre-typed, so you can drag on the gameobject itself and it’ll auto assign.

          The tutorial needs to make this clearer.

    • Jens van de Water
      Posted at 15:04h, 31 October Reply

      At what point in the tutorial are you? Would make it easier to find possible errors. One idea that comes to mind is the synchronized values in OnSerializeNetworkView() are switched. If you send 2 Vector3 values (position first, velocity second) then you should receive them in the same order! Otherwise these values are mixed up. This would lead to the problem you’re describing, but it could be something else entirely.

  • Troy
    Posted at 06:51h, 27 October Reply

    This is excellent! Thank you guys so much for this tutorial – I’m super glad I backed your game on Kickstarter, and was actually disappointed it never got off the ground – I hope you guys find your funding and are able to make the game anyway!

  • Banini
    Posted at 14:35h, 29 October Reply

    Hi, great tutorial !

    I have one problem btw. One I connect 3 player, the last one move very quickly. I think, He get information of other player at the start (every one in the same x,y,z, so he fly on one direction. How to fix that ?

    • Oskari Leppäaho
      Posted at 21:43h, 10 January Reply

      I had a similar problem even with 2 players: When I joined to the server the two cubes started at the spawn position in the joining player’s window which resulted to a collision making them bounce off each other. This started to happen after adding the Interpolation or Prediction, not sure which one. I fixed it like this:

      bool firstUpdate = true;

      void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
      {
      Vector3 syncPosition = Vector3.zero;
      Vector3 syncVelocity = Vector3.zero;
      if (stream.isWriting)
      {
      syncPosition = rigidbody.position;
      stream.Serialize(ref syncPosition);

      syncVelocity = rigidbody.velocity;
      stream.Serialize(ref syncVelocity);
      }
      else
      {
      stream.Serialize(ref syncPosition);
      stream.Serialize(ref syncVelocity);

      if(firstUpdate)
      {
      rigidbody.position = syncPosition;
      firstUpdate = false;
      }

      syncTime = 0f;
      syncDelay = Time.time – lastSynchronizationTime;
      lastSynchronizationTime = Time.time;

      syncStartPosition = rigidbody.position;
      syncEndPosition = syncPosition + syncVelocity * syncDelay;

      Debug.Log(“syncPosition: ” + syncPosition + “, syncDelay: ” + syncDelay
      + “, syncStartPosition: ” + syncStartPosition + “, syncVelocity: ” + syncVelocity );
      }
      }

  • Jens van de Water
    Posted at 15:12h, 31 October Reply

    Sorry, I don’t fully understand the problem you’re having. If you think it is due to the data received when joining, you chould check out whether or not it is buffered. For example, with RPCMode.OthersBuffered, a player that connects later will still receive this information.

  • Kararan
    Posted at 04:34h, 05 November Reply

    thx so much for this great tutorial! thumbs up 🙂

  • Caker
    Posted at 19:16h, 19 November Reply

    I followed the entire tutorial but it does not work, I am 100% positive I did everything correctly, and follow the tutorial about 4 times now to no avail. My issue is that when I build and run > start a server > join the server with the editor > start walking around in the non editor (the game) I do not see it updating the positions at all.

    It only updates the position when I click on the window. So for example I move around in the editor, then click on the game I will see the character from the editor teleport to that position, it’s the same the other way around, it doesn’t update until it’s an active window.

    I even went as far as copying the code from the project files provided but I have the same issue. Also maybe worth to note is that when I press on the “RoomName” to join the server nothing happens, unless i switch to the game, then back to the editor or the other way around, only then it will join.

    • Caker
      Posted at 01:46h, 20 November Reply

      Ignore that, it is in fact working however I don’t see it updating in real time when the window isn’t active. Thanks for the tutorial.

  • mr.Doom
    Posted at 18:01h, 21 November Reply

    How you assigned prefab that should be spawned? You didnt mentioned it and even after going through source files for 3rd time I can´t find where is decided that Player.prefab is going to be spawned

    • mr.Doom
      Posted at 18:08h, 21 November Reply

      Nvm, solved in comment above, sorry

  • Devoted
    Posted at 10:40h, 22 November Reply

    If I wanted to would it be possible to put the server into a completely different build? So this way there is only one host. That handles lets say 1,000 players max.. ? Is it this method not good enough.

  • Nuggeta
    Posted at 20:32h, 27 November Reply

    Really nice article. Specially Interpolation part. Make it even more easy to program with full object data communication with http://nuggeta.com Unity3D API

  • Jamie
    Posted at 11:48h, 28 November Reply

    Hey thanks for the tutorial, I have implemented it into my game and runs fine localy, but how would I go about running this across a router or LAN, thank you

  • Scott
    Posted at 18:25h, 12 December Reply

    where it says ‘private const string typeName=”UniqueGameName”;’ there is a highlighted parsing error under const how do I fix this?

    • Karlo
      Posted at 14:05h, 02 February Reply

      me too

      • Karlo
        Posted at 14:06h, 02 February Reply

        Assets/NetworkManager.cs(1,13): error CS8025: Parsing error

        same like ur

    • springwater
      Posted at 18:20h, 11 May Reply

      I believe the quotation marks that were copied and pasted don’t jive with your editor.. just erase them and retype them. it worked for me

  • Ryan
    Posted at 03:10h, 17 December Reply

    First, Thanks so much for this awesome tutorial. I’m having a couple of problems though. I’m using my own character movement script which uses update to control all the character movement so I just put your if statement in the update function with the brackets surrounding everything in the function. It seems to be working fine, I just wanted to mention it in case it is the cause of one of these problems. So the first problem is that when I use two instances of the game, one to start and one to join a server, the player prefab drops in just fine on both but then when I switch from one instance of the build to another, I’m still only controlling the player prefab who most recently entered the server. The second problem is that I can’t implement the last half of this tutorial because Unity will not let me use a script in the “observed” portion of the Network View component. Very confusing. I’m in the latest Unity pro build (4.3.1f1). Thanks so much for this tutorial again and for taking some time to answer people’s questions. It’s going above and beyond. Any help is appreciated.

    • Ryan
      Posted at 03:32h, 17 December Reply

      Actually, it appears to be working correctly. I added in some objects to stand the players next to to see what was going on. Strangely, the cameras are switched. So the person who joins the server takes over the host camera and the host takes over the joined player’s camera… really weird. I have the camera embedded into the player prefab. Dunno if that’s why. Again… plz help!! 😉

      • Xirre
        Posted at 07:25h, 18 December Reply

        Yeah, I have the same problem, sadly. I’m working on it right now and I have been working on it for about a week now. If you do find a solution, please share. If you’d like to talk with me about solving this issue, let me know.

      • Xirre
        Posted at 19:16h, 18 December Reply

        I got it working. What you need to do is disable your camera and everything else. If you have mouse look, make sure you make a new script (or edit your current one) so that it doesn’t move the camera unless networkView.isMine. Do this in the Update() and Start() functions.

        Now that you have it so that it checks if the camera is theirs and you also have it so that all components are disabled, do the following: Enable Character Controller, your MouseLook with networkView.isMine checking if its theirs, Mesh Renderer for changing the color of your object, Network View (Both on your prefab and the main camera attached to it), and now, make a new script that will also be enabled called “Network Instantiate”.

        In it, you will want to do the following:

        void Start () {
        if(networkView.isMine) {
        if(networkView.GetComponent() != null)
        networkView.GetComponent().enabled = true;
        if(networkView.GetComponent() != null)
        networkView.GetComponent().enabled = true;
        if(networkView.GetComponent() != null)
        networkView.GetComponent().enabled = true;
        if(networkView.GetComponent() != null)
        networkView.GetComponent().enabled = true;
        if(networkView.GetComponent() != null)
        networkView.GetComponent().enabled = true;
        if(networkView.GetComponent() != null)
        networkView.GetComponent().enabled = true;
        }
        else {
        name += “Remote”;
        }
        }

        Network Instantiate should be on your prefab and the main camera attacked. The if statements can be used to differentiate between the two because your main camera will not have a character controller but it will have a camera component. Now that its enabled as soon as the prefab is instantiated, it belongs to whoever enabled it.

        • Ryan
          Posted at 22:42h, 18 December Reply

          Xirre,

          Ok awesome. I’m gonna go try this right now. Thanks for posting your solution!

        • Ryan
          Posted at 23:00h, 18 December Reply

          Xirre,

          I’m not a coder by any stretch of the imagination. I’m sure I’m not just supposed to copy and paste the code you put for the Network Instantiate script but I’m not sure what I’m supposed to be inserting.

        • Ryan
          Posted at 23:18h, 18 December Reply

          Xirre,
          Sorry. I figured it out. Looked up the proper usage of GetComponent in the docs and applied it to all the disabled components in the camera. I’m testing now and it appears to be working!. Thanks again.

        • Pykee
          Posted at 01:47h, 27 July Reply

          I Have the same issue :/ but im really not that great of a coder so can i have a little guidance, thanks!

          • Chad
            Posted at 01:50h, 13 January

            I would like some help with this as well. Any time a person joins my game, he/she takes control my my character and vise versa. How can I maintain camera and movement control when someone joins my game?

  • Game Programming Adventures #2 | The Art of SethJH
    Posted at 15:17h, 18 December Reply

    […] followed a tutorial on network programming in Unity. After a few hours of hacking at it, I was able to connect to my […]

  • Jens van de Water
    Posted at 20:10h, 18 December Reply

    A quick notice from my side: Sorry for not replying to the questions lately, we are very busy at the moment and unable to help. I hope to have time as soon as possible to answer any remaining questions. Thanks for the compliments and support so far! 🙂

    • emperor1lee
      Posted at 15:26h, 10 January Reply

      Hi can you put in that the build instance of the game must have run in background checked, so both can connect to each other

  • Tim
    Posted at 10:58h, 19 December Reply

    Error 500 if I try to download the example from your Dropbox. Can you please fix that? I just want to try your example to get an short overview over the network capabilities of Unity3D.

  • Paul
    Posted at 22:57h, 08 January Reply

    Hi,

    Love the tutorial. Really helped me a lot!

    One question (with preface):
    Sometimes I see two “RoomName” buttons show up.
    I only click the “StartServer” button once.
    Is there a way to stop it from doing that?

    Is it actually creating two servers?
    Could it be a server left in memory from my last multiplayer test?

    Thanks.

    — Paul

    • Thegameboy
      Posted at 00:11h, 15 January Reply

      I had the same problem. The funny but yet disturbing thing is that you’re not making that server. This tutorial’s code connects to Unity’s main server, so you’re picking up other people’s projects. Just change the typeName variable to something unique.

      • Paul
        Posted at 00:29h, 15 January Reply

        Thanks for the info. That is a little scary. I ran some code that just looked for available servers and six other servers showed up in addition to mine. I have since changed my code so it only looks for my unique server name.
        I hope there’s no internet vulnerability involved with this type of thing.

  • Jeremy
    Posted at 00:26h, 13 January Reply

    you should explain that to move the playerscript file to the networkview(observed) field you need to drag it from the inspector window not the project window

  • jeremy
    Posted at 07:46h, 17 January Reply

    I believe the way RPC is done in this example doesnt carry over well to implementing something similar very well….

    considering the RPC function calls itself…..

  • Henris
    Posted at 21:04h, 04 March Reply

    No one can join my game – they see its name when servers get refreshed, but when u click on it nothing happens, we tried original game – same thing. What may be the problem? cheers.

  • Henris
    Posted at 21:12h, 04 March Reply

    Also how to change spawning player location? I tried putting transform.position = Vector.3(153,214,142) between the player.spawn()
    But it teleport`s my network manager thing (plane) to the specified location, not the new player.
    Help Please 🙂

  • taotaojonas
    Posted at 12:16h, 08 March Reply

    Hi,

    Nice tutorial. I was wondering about one thing though. When I have connected more than 3 or 4 players, the cube flies off the screen for some reason. Have you tested using 4 players?

    Keep up the good work!

    • Tuna
      Posted at 19:48h, 22 March Reply

      I think my problem is related. When it’s synced, it assumes the other box’s position from the origin of the spawn. So at 0 second, any other players joining to the server, will have all the other boxes(along with his own) at the origin(in this case, at 0, 5, 0). Since it’s rigidbodies, it’ll cause all the boxes to collide with each other. At first the other boxes will fly out, but it’ll go back to its correct synced position(since, on the server side, they don’t start off from the origin).

      Spawning at the origin is not the problem, I think. The problem is, sync-ing other cubes always starts from the origin, instead of immediately taking their real current position. Whatever I change it to(changing to transform.localPosition) doesn’t fix it.

  • Lucas
    Posted at 04:42h, 07 April Reply

    When a load another scene my player dont spawn .-.
    I used DontDestroyOnLoad but dont works.
    How to fix this mans?

  • David
    Posted at 14:06h, 10 April Reply

    Thank you for this tutorial! It’s really helpfull and concise given the topic

  • chokoladenudlen
    Posted at 14:06h, 30 April Reply

    Thanks for this tutorial. It helped me out a great deal!

  • How to create an online multiplayer game with Unity » Paladin Studios - appgong
    Posted at 16:27h, 06 May Reply

    […] How to create an online multiplayer game with Unity » Paladin Studios […]

  • How to create an online multiplayer game with Photon Unity Networking » Paladin Studios
    Posted at 17:04h, 08 May Reply

    […] small online multiplayer game using Photon Unity Networking (PUN). This project will be similar to “How to create an online multiplayer game with Unity”, but instead of the standard Unity networking, we will use […]

  • fox2402fox2402
    Posted at 14:11h, 16 May Reply

    Hi there, im blocked, i can’t connect to the server i’ve just created (well, i can see it when i refresh but when i click on the button nothing happens, the button works because i’ve tried a Debug.Log). Here’s my code
    private const string typeName = “theUniqueISNTankGame”;
    private const string gameName = “roomName”;
    private HostData[] hostData;
    // Use this for initialization
    private void StartServer()
    {
    Network.InitializeServer(4, 25000, !Network.HavePublicAddress());
    MasterServer.RegisterHost(typeName,gameName);
    }
    private void refreshList()
    {

    MasterServer.RequestHostList(typeName);

    }
    private void joinServer(HostData hostdata)
    {
    Network.Connect(hostdata);

    }
    void OnConnectedToServer()
    {
    Debug.Log(“Server joined”);
    }
    void OnMasterServerEvent(MasterServerEvent mSEvent)
    {
    if (mSEvent == MasterServerEvent.HostListReceived)
    {
    hostData = MasterServer.PollHostList();
    }
    }
    void OnServerInitialized()
    {
    Debug.Log(“Server Initializied”);
    }

    void OnGUI()
    {
    if (!Network.isClient && !Network.isServer)
    {
    if (GUI.Button(new Rect(100,100,250,100), “Start Server”))
    {
    StartServer();
    }
    if (GUI.Button(new Rect(100,250,250,100),”Refresh List”))
    {
    refreshList();

    }
    if (hostData!=null)
    {
    for (int i = 0; i <hostData.Length; i++)
    {
    if(GUI.Button(new Rect (400, 100+(110*i), 250, 100), hostData[i].gameName))
    {
    joinServer(hostData[i]);
    Debug.Log ("CLIIIICK");
    }
    }
    }
    }
    }

    // Update is called once per frame
    void Update () {

    }
    }
    Hope someone can help me out, because without this i'm like… screwed…

  • Mohamed Emam | Windows Game Development With Unity3D
    Posted at 20:12h, 28 May Reply

    […] Online multiplayer by Paladin – http://www.paladinstudios.com/2013/07/10/how-to-create-an-online-multiplayer-game-with-unity/ […]

  • jeff77k
    Posted at 22:28h, 02 June Reply

    This tutorial uses the Master Server run by Unity which … maybe up … or maybe not. But you can download and run your own Master Server locally. Then in NetworkManager.cs add:

    MasterServer.ipAddress = “127.0.0.1”;

    There is lots of info out there on running your own Master Server and what the heck the Master Server is in first place =] . This hung me up the first time I tried to run this, otherwise great tutorial!

  • Alex
    Posted at 02:22h, 06 June Reply

    This is a great tutorial! I have one question though, for some reason when I try the movement interpolation, you cannot see the other players moving. However, the strange part is that if you turn away from the player so that the other play is no longer in the camera’s view, and then you look back, the position will now be updated to the actual current position. The other play will then remain to not move until you look away and look back again (somewhat like slender). I do not have any sort of script that is checking whether the player is looking at another player or not, so that cannot be the problem.

  • Baggaiver
    Posted at 23:45h, 26 June Reply

    Hi there, nice tutorial.
    But i have a problem: i’m at “Spawning a player” and when i try to run 2 istances of the build i have the two player swapped each other.
    I’m using the standard assets’ first person controller with the if(networkView.isMine) statement in every kind of Update of every script attached.
    I’ve also tried a solution in an old comment above but nothing changed.
    Can someone help me?

  • Baggaiver
    Posted at 13:18h, 30 June Reply

    Solved.
    It was a conflict caused by multiple cameras, just enable only the player one.

  • Brett
    Posted at 01:42h, 04 July Reply

    Hi, I’m having an issue where one character controls the other character, and vice versa. Please help.

    • Jens van de Water
      Posted at 10:33h, 14 July Reply

      Did you add the “if (networkView.isMine)” check to the function? If not, the objects with react whether it’s theirs to control or not.

      If you did add this, could you explain your problem with more detail? Does a player only move the other character or both of them?

  • Steven
    Posted at 19:29h, 08 July Reply

    Great tutorial, but I’ve run into a wall implementing this with Physics2D.

    I was able to get the players connected and spawning, and could see them both moving, until I got to the State Synchronization section. I can still connect, and see both players, but the clients only see their own player moving, the other player’s position is never updated.

    This is the original State Synchronization code. What needs changing for Physics2D?

    void OnSerializeNetworkView(BitStream stream, NetworkMessageInfo info)
    {
    Vector3 syncPosition = Vector3.zero;
    if (stream.isWriting)
    {
    syncPosition = rigidbody.position;
    stream.Serialize(ref syncPosition);
    }
    else
    {
    stream.Serialize(ref syncPosition);
    rigidbody.position = syncPosition;
    }
    }

    Run in background is on.
    The Player Prefab-script component is set in Observed.
    Only trying with 2 players.
    Tried running 1 client in the unity editor, also tried both clients as stand-alone builds.

    This is all before the Interpolation section. As soon as I implement the State Synchronization section changes with rigidbody2D, the players stop updating.

    • Jens van de Water
      Posted at 10:39h, 14 July Reply

      Steven, did you add the object’s player script to the (same object’s) observe field? Because it sounds that is where it went wrong. Don’t add it from the project to the scene object.

      I have no experience with Physics2D (or Unity2D for that matter), so if the problem is there than I’m sorry I can’t help you with it 🙁

      • Steven
        Posted at 17:14h, 16 July Reply

        Yeah, as I said, I added the Player Prefab-script component to the Observed field.

        Still no luck. Thanks though.

        • Michał
          Posted at 15:16h, 01 September Reply

          Hi Steven, I had the same problem. Change rigidbody.position to rigidbody2D.transform.position.
          It works.

    • David
      Posted at 07:34h, 11 September Reply

      Hey Steven, did you end up finding a solution to this problem? im having the same issue.

    • David
      Posted at 13:54h, 11 September Reply

      Does anyone know how to implement this in 2D? i changed rigidbody to rigidbody2D and it works fine but the second player slowly moves from where he is instantiated down to the ground. he cant be controlled and the other player is only visible in short blinks.

      if i comment out the line: rigidbody2D.position = Vector3.Lerp(syncStartPos, syncEndPos, syncTime / syncDelay); The second player falls normally but i obviously dont have smooth motion.

      Does anyone know what i can change in this line to make it work in 2D?
      any suggestions warmly welcomed. seriously helpful tutorial btw!

  • everystone
    Posted at 02:31h, 15 July Reply

    Thank you so much! Excellent tutorial, I was looking for how to do Interpolation, and this worked perfectly. Cheers

  • A new beginning.. | Battlemaze
    Posted at 13:44h, 18 July Reply

    […] How to create a multiplayer game with unity […]

  • addd
    Posted at 23:16h, 31 July Reply

    it is a awesome solution with floating origin but how do you create it? i dont find the information :/
    http://answers.unity3d.com/questions/754247/z-fighting-issue-how-to-fix-pc-1.html

  • Phillipka
    Posted at 09:22h, 02 August Reply

    Can anyone help me? I can join my own server from the build and Unity editor, but when i send it to a friend, they see the server but cant join it

    • frozenimpact
      Posted at 04:54h, 15 August Reply

      Yea I would appreciate any help in regards to other people joining this server from non-LAN environment

    • chris73it
      Posted at 10:23h, 17 August Reply

      It doesn’t work using the Unity APIs because of NAT: you have to use stuff like Photon Cloud or Photon Server etc where the servers have a real IP address and don’t require to work around NATs.

  • Emre
    Posted at 16:38h, 22 August Reply

    Shouldn’t the client send the input data to another method and server handle the positioning and send back the new position instead of moving the character in client as in this example?

  • jellybellyfred
    Posted at 01:30h, 03 September Reply

    I’m getting this error: Assets/NetworkManager.cs(4,13): error CS8025: Parsing error

    HELP PLEASE!!

    • Furjoza
      Posted at 02:06h, 05 September Reply

      for 99% you forgot “{” or rather “}” somewhere

  • Furjoza
    Posted at 02:05h, 05 September Reply

    BIG LIKE thanks for that tutorial. It changed my life, srsly 😉

  • jonathanlynch
    Posted at 23:02h, 17 September Reply

    When I put the player control script component in the observed slot I no longer get the updated position of the p

  • Beancake123
    Posted at 05:18h, 05 October Reply

    when I put the second
    void OnGUI()
    {
    if (!Network.isClient && !Network.isServer)
    {
    if (GUI.Button(new Rect(100, 100, 250, 100), “Start Server”))
    StartServer();

    if (GUI.Button(new Rect(100, 250, 250, 100), “Refresh Hosts”))
    RefreshHostList();

    if (hostList != null)
    {
    for (int i = 0; i < hostList.Length; i++)
    {
    if (GUI.Button(new Rect(400, 100 + (110 * i), 300, 100), hostList[i].gameName))
    JoinServer(hostList[i]);
    }
    }
    }
    }

    It says that it needs a specific thing for void OnGUI()
    What do I put in
    It also says there is a problem with &&
    Help in English would be much apreciated!

  • Allan
    Posted at 21:04h, 14 October Reply

    Hello,
    I have a similar project but i’m having problems when one of the players are behind a firewall or using a router with the port that i’m using closed. Do you know how can i workaround this? I heard about the NAT Punchthrough but i didn’t found a helpful (and easy) tutorial.
    Thank you in advance, your tutorial is very good 🙂

  • Y05h1
    Posted at 02:34h, 09 November Reply

    If you cant drag and drop the player script to the network view component you can set it in the player script

    private NetworkView view;

    void Awake()
    {
    view= GetComponent();
    view.observed = GetComponent();
    }

    And thanks for the tutorial 🙂

  • Y05h1
    Posted at 03:10h, 09 November Reply

    *GetComponetn”();
    *GetComponent”();

    and i just realized how to drag and drop it, i think i’m too tired to think xD

  • zeppeldep
    Posted at 12:26h, 08 December Reply

    how do I add auto respawn to this? When the players cube goes off the edge, after falling passed -10 in Y I would like to destroy the player the spawn again.
    I added the folowing in the if test to the Update method in the NetworkManager:

    Network.Destroy (playerPrefab.networkView.viewID);
    SpawnPlayer();

    but this results in error .. View ID Allocation: 0 not found during lookup

    Thx for the great tutorial : )

  • zeppeldep
    Posted at 14:21h, 08 December Reply

    OOps! *blush* … fixed it .. just added the if test, to destroy, to the object (cube), then tested for the object in the update of neworkmanage, when the object is not there … spawn .. doh!

  • sixpaths
    Posted at 06:19h, 25 December Reply

    Hi. I am very new to the unity and I need to create a simple two-player game for my class’ final project. I plan to make a rock-paper-scissor game. What I want to know is how can I get the other layer input key (so I can determine who the winner is)? Thx. Anyway, great tutorial.

  • Chad
    Posted at 01:43h, 13 January Reply

    This is amazing! Thank you! I am stuck and i’m not sure why. Whenever player 2 joins player 1 and player 2 swap controls. (I am controlling my friends character on his screen and he has control of my screen). Has anyone ran into this??

  • Eric
    Posted at 00:29h, 19 January Reply

    I got a parsing error on the first step.

    • Eric
      Posted at 00:45h, 19 January Reply

      Nevermind.

  • Andy
    Posted at 13:09h, 28 January Reply

    Hi, I have followed your tutorial but what I am finding is when I connect a 3rd instance, it can only see the server player gameobject and not player 2 gameobject?

    If the server and player 2 have already spawned and a 3rd connects, should the server and player 2 get automatically spawned on player 3’s instance?

  • Erik Sillén
    Posted at 21:58h, 18 February Reply

    Thanks a lot! I’ve wanted to have exactly this!

  • Gad Hadd
    Posted at 08:32h, 14 March Reply

    Can anyone answer my question??
    I had added an option to quit the server i.e. Network.disconnect();
    Now when i disconnect, the player cubes remain there only and not get destroyed.
    Can anyone tell me what to add to the script to destroy all player objects when server (not a client) is closed??? So that on clicking Start Server a new game is started…

  • Player position on second player connection | DL-UAT
    Posted at 19:35h, 18 March Reply

    […] run my game for the multiplayer part. I’m creating a 2d game. I have followed this tutorial : http://www.paladinstudios.com/2013/07/10/how-to-create-an-online-multiplayer-game-with-unity/ and i’ve implemented it. As the tutorial say, i have a network view pointing to a script, […]

  • Player position on second player connection | Question and Answer
    Posted at 06:50h, 28 March Reply

    […] run my game for the multiplayer part. I’m creating a 2d game. I have followed this tutorial : http://www.paladinstudios.com/2013/07/10/how-to-create-an-online-multiplayer-game-with-unity/ and i’ve implemented it. As the tutorial say, i have a network view pointing to a script, […]

  • Ray Haggins
    Posted at 16:56h, 01 April Reply

    How many Players can be added and can it become like ourworld, club penguin, etc

  • dendriel
    Posted at 18:15h, 28 April Reply

    Thanks for this tutorial!

  • Game a Week: Week 35 | Ms Minotaur
    Posted at 02:49h, 02 June Reply

    […] got a networked multiplayer game to work. Thanks to a wonderful tutorial that I found by Paladin Studios, I had networking up and running in Unity in no time. This tutorial […]

  • Zan97
    Posted at 19:33h, 25 June Reply

    Thanks for this tutorial, but i have a problem: if i use the command “MasterServer.ipAddress = “127.0.0.1”;” to start the server in local, i get this error: “Failed to connect to master server at 127.0.0.1:23466”.
    What can i do to resolve this? Thank you

  • Adham
    Posted at 04:41h, 08 July Reply

    How can i make the other player become another shape ???

  • (Unity) Optimised networking solution for many moving objects | Question and Answer
    Posted at 10:50h, 09 July Reply

    […] However, the issue arises when I try to network this game. I have already attempted to follow this guide to implement this feature: http://www.paladinstudios.com/2013/07/10/how-to-create-an-online-multiplayer-game-with-unity/ […]

  • Jesu
    Posted at 08:31h, 19 July Reply

    If you want to make a localhost master server, you must download Master Server code from Unity, build and run it, so you can connect to your localhost, otherwise, it will fail to connect.

    • Trenton
      Posted at 22:03h, 03 August Reply

      How can you do this?

  • Funkey Pigeon
    Posted at 12:51h, 29 July Reply

    Hi, I’ve done what you said but when I try and move the player, I control the wrong one (I’m doing it first person)

  • Kevin
    Posted at 18:39h, 07 August Reply

    Is there a Limit as to how manny people can play online with this method?

  • offf
    Posted at 17:53h, 19 August Reply

    fuck you

  • Dennis
    Posted at 14:27h, 04 September Reply

    Not works since Unity 5 as the function is deprecated

    Heres the error code:
    Assets/Player.cs(89,53): warning CS0618: `UnityEngine.NetworkView.RPC(string, UnityEngine.RPCMode, params object[])’ is obsolete: `NetworkView RPC functions are deprecated. Refer to the new Multiplayer Networking system.’

    More info about the new Multiplayer Networking system here:

  • Player position on second player connection | TRIFORCE STUDIO
    Posted at 03:46h, 15 December Reply

    […] run my game for the multiplayer part. I'm creating a 2d game. I have followed this tutorial : http://www.paladinstudios.com/2013/07/10/how-to-create-an-online-multiplayer-game-with-unity/ and i've implemented it. As the tutorial say, i have a network view pointing to a script, […]

  • Create Online Game With Unity
    Posted at 23:12h, 04 March Reply

    […] How to create an online multiplayer game with Unity … – A step by step guide on how to create an online multiplayer game with Unity […]

  • Make Online Game Unity | KundgameKundgame
    Posted at 20:38h, 21 March Reply

    […] How to create an online multiplayer game with Unity … – A step by step guide on how to create an online multiplayer game with Unity […]

  • » Create A Building Online GameVergamet Game
    Posted at 19:44h, 09 April Reply

    […] How to create an online multiplayer game with Unity … – A step by step guide on how to create an online multiplayer game with Unity […]

  • Create Online Game Tutorial | Playacuare
    Posted at 06:33h, 12 April Reply

    […] How to create an online multiplayer game with Unity … – A step by step guide on how to create an online multiplayer game with Unity […]

  • Create Online Game Memory | Heroofsparta Game
    Posted at 04:13h, 30 April Reply

    […] How to create an online multiplayer game with Unity … – A step by step guide on how to create an online multiplayer game with Unity […]

  • unity basic game tutorial | Code goFrance!
    Posted at 18:01h, 30 May Reply

    […] How to create an online multiplayer game with Unity […]

  • unity first game tutorial | Code goFrance!
    Posted at 18:59h, 30 May Reply

    […] How to create an online multiplayer game with unity This tutorial will explain how multiplayer can be implemented using unity’s networking functionality. we didn’t work on an online multiplayer game before, and. […]

  • Niktro
    Posted at 15:08h, 02 August Reply

    Thank you mate, it was very usefull

  • Exploring Remote Multiplayer « Gemserk
    Posted at 15:36h, 26 August Reply

    […] How to create an online multiplayer game with Unity […]

Post A Comment