Overview
Multiplayer is easy works like Save is easy: add a MultiplayerIsEasyComponent to a GameObject and, in its inspector, tick the fields of its components that must be the same in every computer (the position, the health of the player, the color, a list of scores...). The asset sends the changes through the network, moves the objects smoothly, creates and destroys them in every computer and lets you call methods in other computers (RPCs). There are no special variable types: your scripts keep using normal fields.
- A player ready to use in one click: GameObject > Multiplayer is easy > Player.
- Host (server and player at the same time), dedicated server and client, over UDP with its own reliable protocol.
- Select fields of your scripts and of Unity components (Transform, Rigidbody, Light, ...), including lists, dictionaries and [Serializable] classes.
- Server authority or owner authority per object, with interpolation of the movement.
- Player prefab, network prefabs, objects of the scene, RPCs, hooks, scene changes, password, connection approval and network simulation.
- Unity 6 (6000.0) or newer. Works with the Built-in Render Pipeline, URP and HDRP, Windows, Mac, Linux, Android and iOS. Source code of the HUD, the examples and the adapters is included.
Quick start
Two players moving in the same scene, without writing code:
- Open the first scene of your game and use GameObject > Multiplayer is easy > Player. It creates:
- the Network Manager: a GameObject with the MultiplayerIsEasyManager and the MultiplayerIsEasyHUD (the buttons Host, Client and Server to test);
- a Player prefab in
Assets: a capsule with a MultiplayerIsEasyComponent (Authority Owner, so each player controls its own, withTransform/positionandTransform/rotationticked) and a MultiplayerIsEasyMovement (WASD or the arrows). It is the Player Prefab of the manager; - two Spawn Points.
- Save the scene and put it first in the scene list of the build (File > Build Profiles, Scene List).
- Test with two players: use Window > Multiplayer is easy > Test with two players (Multiplayer Play Mode). The first time it installs Multiplayer Play Mode, a free package of Unity (until then, in Unity 6.0 Window > Multiplayer only has Multiplayer Center), and opens its window: tick Player 2 and press Play. Press Host in one window and Client in the other. You can also make a build (File > Build And Run) and press Host in one copy and Client in the other (see Testing your game).
Then make it your game: tick more fields, add your scripts to the player, place network objects in the scene... A field of your script is synchronized when you tick it, the computer that controls the object changes it and the others receive it:
using MultiplayerIsEasy;
using UnityEngine;
public class Health : MultiplayerIsEasyBehaviour {
public int Hp = 100; // tick "Health/Hp" in the MultiplayerIsEasyComponent of the player
public void TakeDamage(int damage) {
if (HasAuthority) // only the computer that controls this player changes it
Hp -= damage;
}
}
You don't need to write code to synchronize: whatever the computer with the authority writes in a ticked field appears in the other computers. Read the value of the field as usual.
To make the player by hand: add a MultiplayerIsEasyComponent to the root of a prefab (Add Component > Multiplayer is easy, the
position and the rotation come ticked), set its Authority to Owner, move it only where HasAuthority is true
(MultiplayerIsEasyMovement is a good start), drag the prefab to the Player Prefab of the manager and don't leave a
copy in the scene. The inspector of the manager warns you, with a button to fix it, if the Player Prefab is missing something.
Examples
The folder Multiplayer is easy/Examples has two scenes. Open one, press Play, press Host, and start a second copy of the
game as Client. When you press Play in an example scene you are asked to add the example scenes at the top of the scene list of
the build, so you can make a build to test (remove them from the list before building your own game).
| Scene | What it shows |
|---|---|
| Example 1 - Players | The player prefab (ExamplePlayer) with owner authority: each player moves with WASD, changes its color with C
(a field with a [SyncHook]) and says hello with E (an RPC that runs in every computer). The name comes from the HUD with ConnectionData. |
| Example 2 - Coins | Server authority: only the server creates coins (MultiplayerIsEasyAPI.Spawn), decides who takes them and
despawns them. The Scoreboard is an object of the scene with two ticked fields (Scores and CoinsTaken) and an RPC that any client can call. |
The examples use a small shader that works in every render pipeline. They work with the old Input Manager and with the new Input System.
How it works
- Server: the computer that has the real state of the game. Everything goes through it.
- Client: a player connected to the server. Each client has an id (1, 2, 3...). The server is the id 0
(
MultiplayerIsEasyAPI.ServerClientId). - Host: a server that is also a player (client id 0). It is the easiest way to play: one player hosts, the others join. The host and the server are the same id, so an object owned by the host is owned by the server.
- Network object: a GameObject with a MultiplayerIsEasyComponent. Each one has a
NetworkIdthat is the same in every computer, an owner (a client id) and an authority (who changes its fields).
Thirty times per second (the Tick Rate) the computer with the authority of each object compares its ticked fields with the last values that were sent and sends only what changed. Fields are sent reliably and in order; the movement of the Transform is sent unreliably (the newest state replaces the old one) and the final position is always confirmed. The other computers show the object a little in the past (the Interpolation Delay, 0.1 s by default) so it moves smoothly between the states that arrive. Each state carries the time when its owner took it, and if the states of an object take longer to arrive (a slow network, or an object moved by another client, that goes through the server) the delay of that object grows automatically, so it keeps moving smoothly instead of stopping.
A client that joins late receives the whole game: every network object with the current values of its fields. All the objects are created before their values are applied, so a reference from one object to another one arrives too, whatever their order.
The manager
You need one MultiplayerIsEasyManager in the first scene of the game. By default it is kept when other scenes are loaded (and so
the connection). Most of the time you use the static class MultiplayerIsEasyAPI instead of the component.
| Setting | Description |
|---|---|
| Address / Port | Where the clients connect (an IP, a domain or localhost) and the UDP port of the server (7777 by default). |
| Max Clients | Maximum number of remote clients (the host is not counted). |
| Password | If it is not empty, the clients need the same password to join. |
| Tick Rate | Times per second that changes are sent (30 by default). |
| Timeout | Seconds without receiving anything before a connection is closed. |
| Interpolation Delay | Minimum seconds in the past that remote objects are shown (0.1 s, about three ticks, works well). On slower networks it grows automatically for each object. |
| Check Application Version | Reject clients with a different Application.version (Project Settings > Player > Version). |
| Player Prefab | Created for every player that joins (and for the host), owned by that player. Optional. The inspector warns you, with a button to fix it, if it has no MultiplayerIsEasyComponent, if its Authority is Server (only the server could move the players) or if a copy of it was left in the scene. |
| Spawn Points | Where the players are created, one after the other. If it is empty, or its points were destroyed with their scene, the MultiplayerIsEasySpawnPoint of the loaded scenes are used (the easiest option for games with several scenes). |
| Add All Network Prefabs | On by default: every prefab of the project that has a MultiplayerIsEasyComponent in its root can be created with
Spawn, without adding it to a list. They are added when the game starts and in the builds; the prefabs of the examples only in the
example scenes. It needs the manager in a scene of the build: for a manager created from a prefab, turn it off and use the list. |
| Network Prefabs | The prefabs that can be created with Spawn when Add All Network Prefabs is off. Press Find all network prefabs
to add every prefab of the project that has a MultiplayerIsEasyComponent. |
| Keep Between Scenes | Keep the manager and the connection when another scene is loaded (it uses DontDestroyOnLoad). |
| Run In Background | Keep running without focus (needed to test two windows in the same computer and for servers). |
| Auto Start | Start as Host, Server or Client when the game starts (one frame after it, so the Start of your scripts runs first). |
| Server In Batch Mode | A build started without graphics (-batchmode, a dedicated server) starts the server automatically. |
| Log Level | Which messages of the asset are shown in the console. |
| Network Simulation | Latency (ms), jitter (ms) and packet loss (%) to test a bad network. Only in the editor and in development builds. |
| Events | UnityEvents for Server Started/Stopped, Client Connected/Disconnected (server) and Connected/Disconnected (client), folded at the end of the inspector. |
Below the settings, Test with two players installs or opens Multiplayer Play Mode. In Play mode the inspector of the manager shows the state of the network (ping, traffic, clients) and buttons to start and stop.
Every setting can also be changed from code before starting, for example from the menu of your game:
MultiplayerIsEasyManager manager = MultiplayerIsEasyManager.Instance;
manager.Address = addressField.text;
manager.Password = passwordField.text; // the same as MultiplayerIsEasyAPI.Password
manager.MaxClients = 8;
manager.AddNetworkPrefab(bulletPrefab);
manager.SpawnPoints = new[] { spawnA, spawnB };
MultiplayerIsEasyAPI.StartHost();
When the scene of the manager is loaded again (for example to restart a round), the new copy of the manager destroys its GameObject (and the HUD on it): the manager that was kept between scenes stays, with its connection, and takes the Spawn Points of the loaded scene.
Selecting the fields
The inspector of the MultiplayerIsEasyComponent shows every component of its GameObject as a tree. Tick the fields that must be
synchronized. Groups can be opened to tick only some of their fields, a closed group shows how many fields are ticked, and the
? next to a field explains it (move the mouse over it, or click it). The search box at the top filters the tree. When you add the
component in the inspector, Transform/position and Transform/rotation come ticked. The colors: orange for
[AlwaysSync], blue for the interpolated Transform values and purple for fields with a [SyncHook].
- Transform:
position,rotationandlocalScale. They are compressed, sent unreliably, interpolated and confirmed when the object stops. Tick only what changes: a coin that never moves after it is spawned needs nothing, because the position is sent with the spawn. - Your scripts: their fields (public and private) and their properties with get and set. Nested [Serializable] classes and structs are shown as groups, so you can tick a single field inside them.
- Unity components: their public properties with get and set, for example
Light/intensity,Rigidbody/linearVelocityorGameObject/active. The common ones are shown first and the rest inside More properties.
Other settings of the component:
| Setting | Description |
|---|---|
| Authority | Server: only the server changes the fields. Owner: the owner of the object changes them (the player that controls it). While the server owns it, it behaves like Server. |
| Interpolate | Move remote objects smoothly between the received states. Without it they jump to each new state. |
| Use Local Space | Synchronize the local position and rotation (relative to the parent) instead of the world ones. |
| Destroy With Owner | When the owner leaves, the object is despawned. If it is off, the server becomes the owner. |
| Kinematic When Remote | In the computers without the authority the Rigidbody (or Rigidbody2D) is kinematic, so physics do not fight with the network. |
| Position / Rotation / Scale Threshold | Smaller changes are not sent. |
The fields can also be chosen by code before the object is spawned: SetSynced("Player/Health", true), IsSynced(path) and
SyncedFields. A path is the name of the component and the names of the fields separated by /, as the tree shows them:
Transform/position, Player/Stats/Speed (a field inside a nested class) or GameObject/active (calls SetActive). A group selects all its fields, like its checkbox in the tree:
Player/Stats or Player.
In an editor script that changes a prefab, save it after (PrefabUtility.SavePrefabAsset, or EditorUtility.SetDirty on the
component). If you rename a field or a component, the inspector shows the ticked fields that do not exist anymore.
Every computer must run the same build: the ticked fields and the RPCs of every network prefab are compared when a client
connects, and a client with different ones is rejected (VersionMismatch). The message says which prefab is different.
What can be synchronized
- Numbers (
int,float,double,long,byte, ...),bool,char,string, enums (yours and Unity's, likeKeyCodeorLightType),DateTime,TimeSpan,Guidand nullable values. - Unity types:
Vector2,Vector3,Vector4,Vector2Int,Vector3Int,Quaternion,Color,Color32,Rect,RectInt,Bounds,BoundsInt,LayerMaskandMatrix4x4. - Arrays,
List<T>andDictionary<K, V>of those types, and classes and structs with[System.Serializable](a list or a nested class is sent whole when something inside it changes). - References to network objects: a field of type
GameObjector of a component, that points to an object with a MultiplayerIsEasyComponent that is spawned, arrives as a reference to the same object in the other computers. Each copy of a prefab is a different object in the network, so a reference points to the right copy. They also work in lists and as RPC parameters. A reference to an object that is not in the network arrives asnull.
Assets (materials, textures, prefabs, ScriptableObjects), UnityEvents and delegates cannot be synchronized; the tree does not show them. Send an index or a name instead and look up the asset in each computer. Messages can be up to 4 MB (strings up to 1 MB).
Spawning objects
Only the server creates and destroys network objects; the clients create them automatically. With Add All Network Prefabs (on by
default) any prefab with a MultiplayerIsEasyComponent in its root can be spawned. Without it the prefab must be in the Network Prefabs
of the manager (or registered with MultiplayerIsEasyAPI.RegisterPrefab in every computer before starting).
if (MultiplayerIsEasyAPI.IsServer) {
GameObject bullet = MultiplayerIsEasyAPI.Spawn(bulletPrefab, position, rotation); // owned by the server
GameObject pet = MultiplayerIsEasyAPI.Spawn(petPrefab, position, rotation, clientId); // owned by a client
MultiplayerIsEasyAPI.Despawn(bullet); // destroyed in every computer
}
- The position and the values of the ticked fields at the moment of the spawn arrive with the object. To set them first, instantiate the
prefab, change it and pass the instance:
MultiplayerIsEasyAPI.Spawn(instance). Later changes are sent as normal updates. - Destroying a network object in the server (
Destroy) despawns it in every computer. Destroying it in a client only removes it in that client. - Each prefab receives an id from the editor (shown in its inspector) when it is created or saved, also by a script. A copy of a prefab or a prefab variant receives its own id. The ids are checked again when you press Play, when you press Find all network prefabs and when you make a build.
- The player prefab is spawned for every player when it joins, at the next spawn point, and despawned when it leaves
(with Destroy With Owner). Get it with
MultiplayerIsEasyAPI.LocalPlayerorGetPlayerObject(clientId).
Objects of the scene
A GameObject placed in a scene with a MultiplayerIsEasyComponent (a door, a scoreboard, a platform) is synchronized automatically when the game starts. The editor gives it a scene id when you add it, duplicate it, save the scene and make a build. All the computers must load the same scene. These objects are owned by the server.
RPCs
An RPC is a method that runs in other computers. Mark it with [MultiplayerRpc] and call it with SendRpc and the name of the method:
public class Door : MultiplayerIsEasyBehaviour {
public bool Opened; // ticked, changed only by the server
public void Use() {
SendRpc(nameof(RequestOpen), RpcTarget.Server); // any client asks the server
}
[MultiplayerRpc(RequireOwnership = false)]
private void RequestOpen(RpcInfo info) {
Debug.Log("The client " + info.SenderClientId + " opened the door");
Opened = true; // runs in the server, the field reaches everybody
SendRpc(nameof(PlaySound), RpcTarget.All, 0.8f);
}
[MultiplayerRpc]
private void PlaySound(float volume) { /* ... */ }
}
| Target | Runs in | In the caller |
|---|---|---|
Server | Only the server (or the host). | Only if the caller is the server, at once. |
All | The server and every client. | Yes, at once. |
Others | The server and every client except the caller. | No. |
Owner | The owner of the object. | Only if the caller is the owner, at once. |
Clients | Every client (and the host), not a dedicated server. | Yes, at once (not in a dedicated server). |
SendRpcToClient(method, clientId, ...) | One client. | Only if it is that client (the host is 0), at once. |
When an RPC runs in the computer that calls it, it runs at once, inside SendRpc. The other computers run it when it arrives.
- The parameters can be any type that can be synchronized. An optional last parameter of type
RpcInfotells who sent it. - By default only the owner of the object can call its RPCs (
RequireOwnership = true); the server can always call them. UseRequireOwnership = falsefor requests that any client can make, and check them in the server. Reliable = falsesends it unreliably (it can be lost, good for effects that are sent often). It must fit in one packet (about 1 KB).- From any MonoBehaviour use the extension
this.SendRpc(...)orMultiplayerIsEasyAPI.SendRpc(this, ...). The script must be on a GameObject with a MultiplayerIsEasyComponent that is spawned. RPCs cannot have overloads,reforoutparameters.
Attributes
| Attribute | Use |
|---|---|
[SyncHook(nameof(Method))] | On a ticked field: the method is called in the computers that receive a new value. It can have no parameters, one (the new value) or two (the old and the new value). It is not called in the computer that made the change. |
[AlwaysSync] | The field is always synchronized, without ticking it (useful in reusable scripts and adapters). |
[ServerAuthority] | On a field of an object with Owner authority: only the server changes it (see Authority). The tree shows it with "(server)". |
[AvoidSync] | On a field, a property or a class: it is not shown in the tree and is never synchronized. |
[MultiplayerRpc] | Makes a method an RPC (see RPCs). |
[SyncHook(nameof(OnHealthChanged))]
public int Health = 100;
void OnHealthChanged(int oldValue, int newValue) {
healthBar.fillAmount = newValue / 100f;
}
Events
Scripts on a network object can derive from MultiplayerIsEasyBehaviour (or implement IMultiplayerIsEasyEvents) to receive:
OnNetworkSpawn(): the object is in the network,IsOwner,HasAuthorityandNetworkIdare valid and the ticked fields already have the values that arrived with it (their[SyncHook]methods run just before). In a client that joins, it runs when the whole game has arrived: the references to other network objects already point to them.OnNetworkDespawn(): the object leaves the network (despawned, the scene changes or the connection stops).IsOwnerandHasAuthoritystill tell what it was, for example to give back the camera.OnOwnershipChanged(previous, current).
MultiplayerIsEasyBehaviour also has IsServer, IsClient, IsHost, IsOwner, HasAuthority, OwnerId and SendRpc.
Global events of MultiplayerIsEasyAPI:
MultiplayerIsEasyAPI.OnServerStarted += () => { };
MultiplayerIsEasyAPI.OnClientConnected += clientId => { }; // in the server, also for the host (0)
MultiplayerIsEasyAPI.OnClientDisconnected += clientId => { };
MultiplayerIsEasyAPI.OnConnected += () => { }; // in the client (and the host), the game is ready
MultiplayerIsEasyAPI.OnDisconnected += reason => { }; // DisconnectReason: Timeout, WrongPassword, ServerFull, Kicked...
MultiplayerIsEasyAPI.OnSceneLoaded += sceneName => { };
OnClientConnected is called when the client already has the game: its player object exists
(GetPlayerObject(clientId)) and the RPCs you send to it arrive. In OnDisconnected, MultiplayerIsEasyAPI.DisconnectMessage
has the text that came with it, for example the reason of a rejection.
Subscribe before the network starts. Auto Start, the command line and Server In Batch Mode start it one frame after the scene starts,
so subscribing in Awake, OnEnable or Start is enough. If your own script starts the network in its Start,
subscribe in Awake or OnEnable.
Ready-made components
They are source code (in Multiplayer is easy/Movement and Multiplayer is easy/Adapters): use them as they are, change them or
copy them as the start of your own scripts.
| Component | What it does |
|---|---|
| MultiplayerIsEasyMovement | Moves the object with WASD or the arrows, only in the computer that controls it (HasAuthority);
the other computers receive the position. Speed and Turn To Direction in the inspector. It works with the new Input
System and with the old Input Manager. The menu Player adds it to the player. |
| MultiplayerIsEasyAnimator | Add it next to an Animator of a network object: the float, int and bool parameters of the
Animator are synchronized (the field Values has [AlwaysSync], nothing to tick), so the animations look the same in
every computer. Change the parameters only in the computer with the authority. For triggers call
GetComponent<MultiplayerIsEasyAnimator>().SetTrigger("Jump") instead of Animator.SetTrigger: it is sent to the other
computers with an RPC. Float Damping smooths the received floats. |
| MultiplayerIsEasyHUD | The buttons Host, Client and Server, the address, the port, the name (ConnectionData) and the password, and the
state of the network. It is added to the Network Manager; replace it with the menu of your game. |
Changing the scene
The server changes the scene for everybody with MultiplayerIsEasyAPI.LoadScene("Level 2"). The clients load it automatically. The
spawned objects are destroyed, the objects of the new scene are synchronized and the players are created again at the spawn points of the
new scene. A client that joins later loads the scene of the server automatically. The scenes must be in the scene list of the build.
Don't use SceneManager.LoadScene while connected.
Connection, password and approval
MultiplayerIsEasyAPI.StartClient("192.168.0.10", 7777)connects to an address;StartClient()uses the Address and Port of the manager.MultiplayerIsEasyAPI.Password = "1234"before starting: the server asks for it and the client sends it. A client with another password is rejected withWrongPassword. The HUD has a field for it; the fields of the HUD that you don't edit show, and keep, what your code set in the manager (address, port, password andConnectionData).MultiplayerIsEasyAPI.ConnectionData = "Ana"before connecting sends a text to the server (a name, a token, a JSON...). The server reads it withMultiplayerIsEasyAPI.GetConnectionData(clientId); for the host (0) it is its ownConnectionData.- The server can decide who joins:
MultiplayerIsEasyAPI.ConnectionApproval = request => { if (request.Data == "banned name") { request.RejectMessage = "You can not join."; return false; } return true; // request.Address is the IP of the client }; - The server can kick a client with
DisconnectClient(clientId). The reason of a disconnection arrives inOnDisconnected, and theRejectMessageinMultiplayerIsEasyAPI.DisconnectMessage.
Testing your game
You need two copies of the game running at the same time:
- Multiplayer Play Mode (Window > Multiplayer > Multiplayer Play Mode, package
com.unity.multiplayer.playmode): runs up to four players from the editor without building. New projects don't have it: Window > Multiplayer is easy > Test with two players (or the button at the end of the inspector of the manager) installs it and opens its window. Tick Player 2, press Play, and press Host in one window and Client in the other. - A build and the editor: put your scene first in the scene list (File > Build Profiles), make a build (File > Build And Run), and press Host in one and Client in the other. Run In Background (on by default) keeps both running.
- Command line:
-mie-host,-mie-server,-mie-client,-mie-address 192.168.0.10and-mie-port 7777start the build automatically, for exampleMyGame.exe -mie-client -mie-address 127.0.0.1. - Network simulation: turn it on in the manager to add latency, jitter and packet loss and see how your game feels on a bad network.
In the same computer use the address 127.0.0.1. In a local network use the IP of the host (for example 192.168.0.10).
Builds and servers
- Over the internet, the server (or the host) must be reachable: open the UDP port in its firewall and, at home, forward the port in the router to that computer. Players join with the public IP or a domain name.
- A dedicated server is a build without graphics that starts the server automatically (Server In Batch Mode). The best way is the
Dedicated Server build target of Unity (File > Build Profiles > Windows Server or Linux Server, a module that you install
from the Unity Hub): it does not need a screen. A normal build started with
-batchmode -nographicsalso works on most computers, but on a Linux server without a display use the Dedicated Server target. Use-mie-portto change the port. - The clients and the server must be the same build (same prefabs, ticked fields and RPCs). With Check Application Version the version must match too.
- IL2CPP (iOS, Android, consoles): Unity removes the code that nobody calls, and the asset uses your fields, RPCs and hooks by
reflection. The asset keeps them: it has a
link.xmlfor its DLL and in each build it adds one with the components of your network prefabs and of the network objects of the scenes of the build. Objects made by code and registered withRegisterPrefabare not known in the build: with a Managed Stripping Level higher than Minimal add[UnityEngine.Scripting.Preserve]to their scripts.
API summary
| MultiplayerIsEasyAPI | |
|---|---|
StartHost(), StartServer(), StartClient(), StartClient(address, port), Stop() | Start and stop the network. |
IsServer, IsClient, IsHost, IsRunning, IsConnecting, IsConnected, LocalClientId | State of this computer. |
Spawn(prefab, [position, rotation], [owner]), Despawn(gameObject), ChangeOwnership(gameObject, clientId), RemoveOwnership(gameObject) | Network objects (server). |
GetNetworkObject(networkId), GetPlayerObject(clientId), LocalPlayer, ConnectedClients | Find objects and players
(GetPlayerObject returns the GameObject, GetNetworkObject and LocalPlayer its MultiplayerIsEasyComponent). |
SendRpc(script, method, target, args), SendRpcToClient(script, method, clientId, args) | RPCs. |
LoadScene(name), DisconnectClient(clientId), RegisterPrefab(prefab) | Server tools. |
Password, ConnectionData, GetConnectionData(clientId), ConnectionApproval, DisconnectMessage | Connection. |
ServerTime, Statistics | The time of the server (the same in every computer) and the ping and traffic. |
OnServerStarted, OnServerStopped, OnClientConnected, OnClientDisconnected, OnConnected, OnDisconnected, OnSceneLoaded | Events. |
| MultiplayerIsEasyComponent | |
|---|---|
NetworkId, IsSpawned, OwnerId, IsOwner, HasAuthority, IsSceneObject, IsPlayerObject | State of the object. |
ChangeOwnership(clientId), RemoveOwnership(), Despawn(), Teleport(position, rotation) | Actions. |
SetSynced(path, synced), IsSynced(path), SyncedFields | The ticked fields. |
Authority, Interpolate, DestroyWithOwner, thresholds... | The settings of the inspector. |
MultiplayerIsEasyManager.Instance has the settings of the inspector as properties (Address, Port, MaxClients,
Password, TickRate, PlayerPrefab, AddNetworkPrefab, SpawnPoints, Timeout,
InterpolationDelay, KeepBetweenScenes, RunInBackground, LogLevel, SimulateNetwork...).
Every class and member has its documentation in the code editor (MultiplayerIsEasyDLL.xml).
Limitations
- WebGL is not supported (browsers do not allow UDP).
- There is no relay or NAT punch-through: the server must be reachable (see Builds and servers).
- No client-side prediction or lag compensation: with owner authority the owner moves at once; with server authority the client sees the result after a round trip.
- Every client receives every network object (there is no interest management). It is designed for small and medium games (up to about 16-32 players).
- The parent of a network object is not synchronized; only the root of a prefab can be a network object (children can have ticked fields only through the components of the root).
- Only one manager per game, and one MultiplayerIsEasyComponent per GameObject.
Troubleshooting
| Problem | Solution |
|---|---|
The client stays in "Connecting" and ends with ConnectionFailed. | Check the address and the port, that the server is running and that the UDP port is open in its firewall. In the same computer use 127.0.0.1. |
The client is rejected with VersionMismatch. | The two builds are different (prefabs, ticked fields, RPCs or Application.version); the message says which prefab is different. Make a new build of both. |
| "The prefab is not in the Network Prefabs". | Turn on Add All Network Prefabs in the manager, or add the prefab to its list. |
| The players do not move, or a player moves two capsules. | Look at the inspector of the Network Manager: it warns if the Player Prefab has Server authority, if its position is not ticked or if a copy of it was left in the scene, with a button to fix it. |
| "The host could not start on the port...". | Another program, or another copy of the game, is using the port. Stop it or use another port. |
| The build starts in another scene. | Put your scene first in the scene list (File > Build Profiles). |
| A field does not change in the other computers. | Is it ticked? Is it changed in the computer with the authority (HasAuthority)? A list or a class must be changed in place or replaced; both are detected. |
| A remote object shakes or lags. | Make sure only the computer with the authority moves it (scripts, animations with root motion, physics). Raise the Interpolation Delay if the network loses packets. |
| The game freezes in the second window. | Turn on Run In Background in the manager (and in Project Settings > Player). |
| An RPC does nothing. | Check the console: the method needs [MultiplayerRpc], the object must be spawned, and by default only its owner can call it. |
API reference
The public classes of the asset, in the MultiplayerIsEasy namespace.
MultiplayerIsEasyAPI
The main class of the asset: start and stop the game, create objects in the network, call RPCs and receive the events. It uses the MultiplayerIsEasyManager of the scene.
MultiplayerIsEasyAPI.StartHost();
MultiplayerIsEasyAPI.StartClient("192.168.0.10", 7777);
MultiplayerIsEasyAPI.Spawn(enemyPrefab, position, Quaternion.identity);
Properties
ConnectionApprovalOnly in the server: decides if a client can join, after the password and the version were checked. Return false to reject it, set
ConnectionRequest.RejectMessageto tell the client why. Set it before starting the server.MultiplayerIsEasyAPI.ConnectionApproval = request => request.Data != "BannedPlayer";ConnectionDataA text that the client sends to the server when it connects, for example the name of the player. The server reads it in
MultiplayerIsEasyAPI.ConnectionApprovaland withMultiplayerIsEasyAPI.GetConnectionData(System.Int32). Set it before connecting.ManagerThe manager of the game, null if there is no
MultiplayerIsEasyManagerin the scene.PasswordThe password of the manager: in the server the clients need it to join, in a client it is the one that it sends. Set it before starting (for example from a text field of your menu).
IsConnectingtrue while a client is connecting (before it receives the game).
DisconnectMessageThe text that came with the last disconnection of this client, for example the
ConnectionRequest.RejectMessageof theMultiplayerIsEasyAPI.ConnectionApprovalof the server. Read it inMultiplayerIsEasyAPI.OnDisconnected.IsServertrue in the server and in the host.
IsClienttrue in a client and in the host.
IsHosttrue in the host (server and client at the same time).
IsRunningtrue if the game was started (as host, server or client).
IsConnectedtrue if the server is running, or if the client finished joining the game.
LocalClientIdThe id of the local game: 0 in the server and in the host, 1 or more in the clients, -1 if it is not connected.
ServerTimeThe time of the server in seconds since it started, in the clients it is estimated. Useful to synchronize timers.
StatisticsStatistics of the network traffic (round trip time, bytes per second, ...).
ConnectedClientsOnly in the server: the ids of the clients in the game, including the host (0).
LocalPlayerThe player object of the local game, null if it does not have one.
Methods
StartHost()Starts the server and a local client at the same time.
Returns: false if it could not start.
StartServer()Starts a dedicated server (without a local player).
Returns: false if it could not start.
StartClient()Connects to the server with the address and port of the manager.
Returns: false if it could not start connecting.
StartClient(string address, int port)Connects to a server.
address: An IP (for example 192.168.0.10), a domain name or "localhost".port: The UDP port of the server.Returns: false if it could not start connecting.
Stop()Stops the server, the host or the client.
Spawn(GameObject prefabOrInstance, int ownerClientId)Creates a network prefab in all the computers (only the server can do it). If it receives an instance of a network prefab that is in the scene, that object is spawned.
prefabOrInstance: A prefab of the Network Prefabs of the manager, or an instance of one.ownerClientId: The id of the owner, 0 for the server.Returns: The created object, null if it could not be spawned.
Spawn(GameObject prefab, Vector3 position, Quaternion rotation, int ownerClientId)Creates a network prefab in all the computers at the position and rotation (only the server can do it).
prefab: A prefab of the Network Prefabs of the manager.position: The position.rotation: The rotation.ownerClientId: The id of the owner, 0 for the server.Returns: The created object, null if it could not be spawned.
Despawn(GameObject networkObject)Removes an object from the network and destroys it in all the computers (only the server can do it). Destroying the object in the server with Destroy() does the same.
networkObject: An object with aMultiplayerIsEasyComponent.RemoveOwnership(GameObject networkObject)Gives a network object back to the server (only the server can do it). The same as
ChangeOwnership(networkObject, 0).networkObject: An object with aMultiplayerIsEasyComponentthat is spawned.ChangeOwnership(GameObject networkObject, int clientId)Changes the owner of a network object (only the server can do it).
networkObject: An object with aMultiplayerIsEasyComponentthat is spawned.clientId: The id of the new owner, 0 for the server.GetNetworkObject(uint networkId)Finds a network object by its id.
networkId: TheMultiplayerIsEasyComponent.NetworkIdof the object.Returns: The object, null if it does not exist.
GetPlayerObject(int clientId)The player object of a client.
clientId: The id of the client, 0 for the host.Returns: The player object, null if the client does not have one.
GetConnectionData(int clientId)Only in the server: the
MultiplayerIsEasyAPI.ConnectionDatathat a client sent when it connected.clientId: The id of the client.Returns: The text, empty if the client does not exist.
LoadScene(string sceneName)Loads a scene in the server and in all the clients (only the server can do it). It must be in the scene list of the build.
sceneName: The name of the scene.DisconnectClient(int clientId)Disconnects a client (only the server can do it).
clientId: The id of the client.RegisterPrefab(GameObject prefab)Adds a prefab to the network prefabs from code. Call it before starting the game, in all the computers.
prefab: A prefab with aMultiplayerIsEasyComponent. It can also be an inactive object of the scene used as a template (for example an object made by code, with the same name in all the computers): the spawned objects are active copies of it.SendRpc(MonoBehaviour behaviour, string method, RpcTarget target, object[] args)Calls a method marked with
MultiplayerRpcAttributein other computers. The GameObject needs aMultiplayerIsEasyComponent.behaviour: The script that has the method.method: The name of the method, use nameof(MyMethod).target: Where the method is executed.args: The parameters of the method.SendRpcToClient(MonoBehaviour behaviour, string method, int clientId, object[] args)Calls a method marked with
MultiplayerRpcAttributeonly in one client. If that client is the caller (or the host calls it for 0), it runs at once.behaviour: The script that has the method.method: The name of the method, use nameof(MyMethod).clientId: The id of the client, 0 for the host.args: The parameters of the method.
Fields
ServerClientIdThe client id of the server, and of the host.
Events
OnServerStartedThe server started (also the host).
OnServerStoppedThe server stopped (also the host).
OnClientConnectedOnly in the server: a client joined the game, it receives the id of the client (0 is the host).
OnClientDisconnectedOnly in the server: a client left the game, it receives the id of the client.
OnConnectedThe local client joined the game and received all the objects (also called in the host).
OnDisconnectedThe local client was disconnected, or it could not connect. It receives the reason.
OnSceneLoadedA scene loaded with
MultiplayerIsEasyAPI.LoadScene(System.String)finished loading in this computer.
MultiplayerIsEasyManager
Manages the network game: starts the host, the server or the client, keeps the list of prefabs that can be created in the network, creates the object of each player and sends the changes of the synchronized fields.
You need one MultiplayerIsEasyManager in the first scene of the game. By default it is kept when other scenes are loaded.
Most of the time you can use the static class MultiplayerIsEasyAPI instead of this component.
Properties
InstanceThe manager of the game, null if there is none. There is only one: when the scene of the manager is loaded again, the new copy destroys its GameObject and this one (kept between scenes, with the connection) takes the Spawn Points of that scene.
AddressThe address of the server that the clients connect to.
PortThe UDP port of the server.
MaxClientsMaximum number of remote clients. Change it before starting the server.
PasswordThe password of the server, or the password that the client sends. Empty for no password.
TickRateTimes per second that the changes are sent. Change it before starting the server, the clients use the value of the server.
PlayerPrefabThe prefab that is created for each player.
AddAllNetworkPrefabsAdd all the prefabs of the project that have a
MultiplayerIsEasyComponentin their root to the network prefabs, when the game starts (in the editor) and in the builds, so the Network Prefabs list is not needed. The prefabs of the examples are only added in the example scenes. In a build it works with the managers placed in the scenes of the build, not with a manager created from a prefab.NetworkPrefabsThe prefabs that can be created in the network (the Network Prefabs list of the inspector). Change it with
MultiplayerIsEasyManager.AddNetworkPrefab(UnityEngine.GameObject)andMultiplayerIsEasyManager.RemoveNetworkPrefab(UnityEngine.GameObject).SpawnPointsWhere the players are created, one after the other. If it is empty the
MultiplayerIsEasySpawnPointof the scene are used.TimeoutSeconds without receiving anything before a connection is closed. It is used the next time the game starts.
InterpolationDelayMinimum seconds in the past that the objects controlled by other computers are shown, so they move smoothly. On slower networks it grows automatically for each object. It is used the next time the game starts.
CheckApplicationVersionReject the clients that have a different Application.version.
KeepBetweenScenesKeep the manager, and the connection, when a new scene is loaded (the "Keep Between Scenes" setting: it uses DontDestroyOnLoad).
RunInBackgroundKeep running when the window does not have the focus.
AutoStartHow the manager starts when the game starts.
ServerInBatchModeIn a build without graphics (batch mode, a dedicated server) the server starts automatically.
LogLevelWhich messages of the asset are shown in the console.
SimulateNetworkSimulate a slow network (only in the editor and in development builds). It is used the next time the game starts.
SimulatedLatencyDelay of each packet that is sent when
MultiplayerIsEasyManager.SimulateNetworkis on, in milliseconds.SimulatedJitterRandom variation of the delay when
MultiplayerIsEasyManager.SimulateNetworkis on, in milliseconds.SimulatedPacketLossPercentage of the packets that are lost when
MultiplayerIsEasyManager.SimulateNetworkis on.DisconnectMessageThe text that came with the last disconnection of this client, for example the
ConnectionRequest.RejectMessageof the server. Empty if there was no text.IsServertrue in the server and in the host.
IsClienttrue in a client and in the host.
IsHosttrue in the host (server and client at the same time).
IsRunningtrue if the game was started (as host, server or client) and it was not stopped.
IsConnectedtrue if the server is running, or if the client finished joining the game.
IsConnectingtrue while a client is connecting or receiving the game.
LocalClientIdThe id of the local game: 0 in the server and in the host, 1 or more in the clients, -1 if it is not connected.
ServerTimeThe time of the server in seconds since it started, in the clients it is estimated.
StatisticsStatistics of the network traffic.
ConnectedClientsOnly in the server: the ids of the clients in the game, including the host (0).
LocalPlayerThe player object of the local game, null if it does not have one.
Methods
AddNetworkPrefab(GameObject prefab)Adds a prefab to the Network Prefabs list, like dragging it in the inspector (a prefab that is already in the list is ignored). In an editor script that sets up a scene, mark the manager dirty after it (EditorUtility.SetDirty) or use Undo, so the scene saves it. In the game, add it before starting and in every computer: the server and the clients need the same prefabs.
prefab: A prefab with aMultiplayerIsEasyComponentin its root.RemoveNetworkPrefab(GameObject prefab)Removes a prefab from the Network Prefabs list.
prefab: The prefab.StartHost()Starts the server and a local client at the same time.
Returns: false if it could not start, for example because the port is in use.
StartServer()Starts a dedicated server (without a local player).
Returns: false if it could not start, for example because the port is in use.
StartClient()Connects to the server at
MultiplayerIsEasyManager.AddressandMultiplayerIsEasyManager.Port. When it finishes joining the gameMultiplayerIsEasyAPI.OnConnectedis called, and if it failsMultiplayerIsEasyAPI.OnDisconnected.Returns: false if it could not start connecting, for example because the address is not valid.
StartClient(string serverAddress, int serverPort)Connects to the server at the address and port.
serverAddress: An IP (for example 192.168.0.10), a domain name or "localhost".serverPort: The UDP port of the server.Returns: false if it could not start connecting, for example because the address is not valid.
Stop()Stops the server, the host or the client. The objects created in the network are destroyed.
RegisterPrefab(GameObject prefab)Adds a prefab to the network prefabs from code. Call it before starting the game, in all the computers.
prefab: A prefab with aMultiplayerIsEasyComponent. It can also be an inactive object of the scene used as a template (for example an object made by code, with the same name in all the computers): the spawned objects are active copies of it.Spawn(GameObject prefabOrInstance, int ownerClientId)Creates a network prefab in all the computers (only the server can do it). If it receives an object of the scene that is an instance of a network prefab, that object is spawned.
prefabOrInstance: A prefab of the Network Prefabs, or an instance of one of them.ownerClientId: The id of the owner, 0 for the server.Returns: The created object, null if it could not be spawned.
Spawn(GameObject prefab, Vector3 position, Quaternion rotation, int ownerClientId)Creates a network prefab in all the computers at the position and rotation (only the server can do it).
prefab: A prefab of the Network Prefabs.position: The position.rotation: The rotation.ownerClientId: The id of the owner, 0 for the server.Returns: The created object, null if it could not be spawned.
Despawn(GameObject networkObject)Removes an object from the network and destroys it in all the computers (only the server can do it).
networkObject: An object with aMultiplayerIsEasyComponentthat is spawned.GetNetworkObject(uint networkId)Finds a network object by its
MultiplayerIsEasyComponent.NetworkId.networkId: The id of the object in the network.Returns: The object, null if it does not exist.
GetPlayerObject(int clientId)The player object of a client.
clientId: The id of the client, 0 for the host.Returns: The player object, null if the client does not have one.
LoadScene(string sceneName)Loads a scene in the server and in all the clients (only the server can do it). The objects created in the network are destroyed and the players are created again. The scene must be in the scene list of the build.
sceneName: The name of the scene.DisconnectClient(int clientId)Disconnects a client (only the server can do it). The client receives
DisconnectReason.Kicked.clientId: The id of the client.
Fields
ServerStartedCalled when the server (or the host) starts.
ServerStoppedCalled when the server (or the host) stops.
ClientConnectedOnly in the server: a client joined the game (it receives its id, 0 is the host).
ClientDisconnectedOnly in the server: a client left the game (it receives its id).
ConnectedThe local client joined the game (also in the host).
DisconnectedThe local client was disconnected (it receives the reason).
MultiplayerIsEasyComponent
To synchronize a GameObject in the network you need this component. In the inspector select the fields of the components that you want to synchronize (the position of the Transform, the health of your script, ...), like in Save Is Easy.
The objects placed in the scene are synchronized automatically. The prefabs that are created during the game must be in the Network Prefabs of the MultiplayerIsEasyManager and they are created with MultiplayerIsEasyAPI.Spawn(UnityEngine.GameObject,System.Int32).
Properties
NetworkIdThe id of the object in the network, the same in all the computers. 0 if it is not spawned.
IsSpawnedtrue if the object is in the network (spawned by the server or an object of the scene in a running game).
OwnerIdThe id of the client that owns the object, 0 (
MultiplayerIsEasyAPI.ServerClientId) if it is owned by the server.IsOwnertrue if the local game owns this object.
HasAuthoritytrue if the local game controls the synchronized fields of this object (see
MultiplayerIsEasyComponent.Authority). Change the fields only where it is true, in the other computers they are overwritten.IsSceneObjecttrue if the object was placed in a scene in the editor (and it is not a prefab spawned during the game).
IsPlayerObjecttrue if it is the player object of a client (spawned with the Player Prefab of the manager).
PrefabIdThe id that identifies the prefab of this object in all the computers. The editor assigns it when the prefab is created or saved (also by a script), and checks it again when you press Play and when you make a build.
SceneIdThe id that identifies this object in the scene in all the computers, 0 if it is not an object of a scene. It is assigned in the editor.
AuthorityWho can change the synchronized fields. Change it before the object is spawned.
InterpolateMove the object smoothly between the states that arrive from the network.
UseLocalSpaceSynchronize the local position and rotation (relative to the parent) instead of the world position and rotation.
DestroyWithOwnerWhen the owner leaves the game the object is despawned. If it is false the server becomes the owner.
KinematicWhenRemoteIn the computers that do not control the object its Rigidbody (or Rigidbody2D) is kinematic.
PositionThresholdSmaller movements are not sent (in units).
RotationThresholdSmaller rotations are not sent (in degrees).
ScaleThresholdSmaller changes of scale are not sent.
SyncedFieldsThe fields selected in the inspector, for example "Transform/position" or "PlayerScript/health".
Methods
IsSynced(string path)true if the field is selected to be synchronized. For a group (a component, or a class or struct inside it) true if all its fields are.
path: The path of the field: the name of the component and the name of the field separated by '/', for example "PlayerScript/health".SetSynced(string path, bool synced)Selects or unselects a field from code, like the inspector. It has to be done before the object is spawned and in the same way in all the computers. In an editor script that changes a prefab, save it after (PrefabUtility.SavePrefabAsset, or EditorUtility.SetDirty on this component).
path: The path of the field as the tree shows it: the name of the component and the names of the fields separated by '/', for example "PlayerScript/health", "PlayerScript/Stats/Speed" (a field of a nested class), "Transform/position" or "GameObject/active". A group selects all its fields, like its checkbox in the inspector: "PlayerScript/Stats" (a nested class or struct) or "PlayerScript" (every field of the component).synced: true to synchronize it.ChangeOwnership(int clientId)Changes the owner of the object. Only the server can do it.
clientId: The id of the new owner, 0 for the server.RemoveOwnership()The server becomes the owner of the object. Only the server can do it.
Despawn()Removes the object from the network and destroys it in all the computers. Only the server can do it.
Teleport(Vector3 position, Quaternion rotation)Moves the object to a new place without interpolation (the other computers do not show it moving through the space in between). Only the computer with the authority can do it.
position: The new position (local ifMultiplayerIsEasyComponent.UseLocalSpaceis true).rotation: The new rotation (local ifMultiplayerIsEasyComponent.UseLocalSpaceis true).SendRpc(MonoBehaviour target, string method, RpcTarget rpcTarget, object[] args)Calls a method marked with
MultiplayerRpcAttributein other computers.target: The script that has the method, it must be in this GameObject.method: The name of the method, use nameof(MyMethod).rpcTarget: Where the method is executed.args: The parameters of the method.SendRpcToClient(MonoBehaviour target, string method, int clientId, object[] args)Calls a method marked with
MultiplayerRpcAttributeonly in one client.target: The script that has the method, it must be in this GameObject.method: The name of the method, use nameof(MyMethod).clientId: The id of the client, 0 for the host.args: The parameters of the method.
MultiplayerIsEasyBehaviour
A MonoBehaviour with shortcuts for the network: IsOwner, HasAuthority, IsServer, SendRpc and the network events as virtual methods. Inheriting from it is optional, any script works with the MultiplayerIsEasyComponent.
public class Player : MultiplayerIsEasyBehaviour {
public override void OnNetworkSpawn() {
if (IsOwner) Camera.main.transform.SetParent(transform);
}
}
Properties
NetworkObjectThe
MultiplayerIsEasyComponentof this GameObject.IsServertrue in the server and in the host.
IsClienttrue in a client and in the host.
IsHosttrue in the host.
IsOwnertrue if the local game owns this object.
HasAuthoritytrue if the local game controls the synchronized fields of this object.
IsSpawnedtrue if the object is in the network.
OwnerIdThe id of the owner of the object, 0 for the server.
NetworkIdThe id of the object in the network.
LocalClientIdThe id of the local game: 0 in the server and in the host, 1 or more in the clients.
Methods
OnNetworkSpawn()The object is now in the network. Use it instead of Start() for the code that needs to know the owner or the synchronized values.
OnNetworkDespawn()The object is no longer in the network.
OnOwnershipChanged(int previousOwner, int newOwner)The owner of the object changed.
previousOwner: The id of the previous owner.newOwner: The id of the new owner.SendRpc(string method, RpcTarget target, object[] args)Calls a method of this script marked with
MultiplayerRpcAttributein other computers.method: The name of the method, use nameof(MyMethod).target: Where the method is executed.args: The parameters of the method.SendRpcToClient(string method, int clientId, object[] args)Calls a method of this script marked with
MultiplayerRpcAttributeonly in one client. If that client is the caller (or the host calls it for 0), it runs at once.method: The name of the method, use nameof(MyMethod).clientId: The id of the client, 0 for the host.args: The parameters of the method.
IMultiplayerIsEasyEvents
Implement this interface in a script of a GameObject that has a MultiplayerIsEasyComponent to receive its network events. You can also inherit from MultiplayerIsEasyBehaviour, that implements it with virtual methods.
Methods
OnNetworkSpawn()The object is now in the network. Use it instead of Start() for the code that needs to know the owner or the synchronized values, in the clients it is called after the values of the server were applied.
OnNetworkDespawn()The object is no longer in the network: it was despawned, the game was disconnected or a new scene was loaded.
OnOwnershipChanged(int previousOwner, int newOwner)The owner of the object changed.
previousOwner: The id of the previous owner (0 is the server).newOwner: The id of the new owner (0 is the server).
MultiplayerIsEasySpawnPoint
Marks a place where the players are created. If the Spawn Points of the MultiplayerIsEasyManager are empty, the players are created at the spawn points of the scene, one after the other (each scene can have its own).
MultiplayerIsEasyExtensions
Shortcuts to use the network from any script.
Methods
SendRpc(MonoBehaviour behaviour, string method, RpcTarget target, object[] args)Calls a method of this script marked with
MultiplayerRpcAttributein other computers.this.SendRpc(nameof(Shoot), RpcTarget.All, direction);behaviour: The script that has the method.method: The name of the method, use nameof(MyMethod).target: Where the method is executed.args: The parameters of the method.SendRpcToClient(MonoBehaviour behaviour, string method, int clientId, object[] args)Calls a method of this script marked with
MultiplayerRpcAttributeonly in one client. If that client is the caller (or the host calls it for 0), it runs at once.behaviour: The script that has the method.method: The name of the method, use nameof(MyMethod).clientId: The id of the client, 0 for the host.args: The parameters of the method.GetNetworkObject(Component component)The
MultiplayerIsEasyComponentof the GameObject of this component, null if it does not have one.component: Any component of the GameObject.Returns: The MultiplayerIsEasyComponent or null.
GetNetworkObject(GameObject gameObject)The
MultiplayerIsEasyComponentof the GameObject, null if it does not have one.gameObject: The GameObject.Returns: The MultiplayerIsEasyComponent or null.
MultiplayerRpcAttribute
Marks a method of a script as a remote procedure call (RPC), so it can be executed in other computers with SendRpc. The GameObject needs a MultiplayerIsEasyComponent.
The parameters can be of any type that can be synchronized (numbers, strings, enums, Vector3, arrays, lists, ...). Add RpcInfo as the last parameter to know who made the call.
[MultiplayerRpc]
void Shoot(Vector3 direction) { ... }
//in another method
this.SendRpc(nameof(Shoot), RpcTarget.All, transform.forward);
Properties
RequireOwnershipIf true (the default) only the owner of the object, or the server, can make the call. Set it to false so any client can make it, for example to open a door that is owned by the server.
ReliableIf true (the default) the call always arrives and in order. If false it is faster but it can be lost, use it for calls that are sent very often and where only the last one matters.
RpcInfo
Information about a remote procedure call. Add it as the last parameter of a method marked with MultiplayerRpcAttribute to know who made the call, it is filled automatically and it is not sent.
[MultiplayerRpc(RequireOwnership = false)]
void OpenDoor(RpcInfo info) {
Debug.Log("The client " + info.SenderClientId + " opened the door");
}
Properties
SenderClientIdThe id of the client that made the call, 0 if it was the server or the host.
RpcTarget
Where a remote procedure call (a method marked with MultiplayerRpcAttribute) is executed. When it runs in the computer that makes the call, it runs at once, inside SendRpc; the others run it when the call arrives.
Fields
ServerOnly on the server (or the host). If the caller is the server, it runs at once.
AllOn the server and on every client, including the one that makes the call (the caller runs it at once).
OthersOn the server and on every client, except the one that makes the call.
OwnerOnly on the owner of the object (the server or host if the object is owned by the server). If the caller is the owner, it runs at once.
ClientsOn every client, including the host, but not on a dedicated server. A client or the host that makes the call runs it at once.
SyncAuthority
Who is allowed to change the synchronized fields of a networked GameObject.
Fields
ServerOnly the server changes the synchronized fields and every client receives them. Changes made by a client are overwritten by the next update of the server.
OwnerThe owner of the object changes the synchronized fields (for example the player that controls it), the server receives them and sends them to the other clients. While the object is owned by the server it behaves like
SyncAuthority.Server.
ServerAuthorityAttribute
Only the server changes this synchronized field or property, also in an object with SyncAuthority.Owner authority. Use it for the values that the game rules decide, for example the score or the health of a player that its owner moves. The changes that the owner makes to it are not sent (the next value of the server replaces them). It can also be put on a field that has a class or a struct inside, then it applies to all its fields.
[ServerAuthority]
public int Score; //the server adds the points, the owner can not change them
SyncHookAttribute
Calls a method of the same class when the synchronized value of the field or property changes because of a value that arrived from the network (it is not called in the computer that made the change).
The method can have no parameters, one parameter (the new value) or two parameters (the old value and the new value).
[SyncHook(nameof(OnHealthChanged))]
public int Health;
void OnHealthChanged(int oldValue, int newValue) {
healthBar.value = newValue;
}
Properties
MethodNameThe name of the method that is called.
Methods
SyncHookAttribute(string methodName)The method is called when the value changes because of the network.
methodName: The name of the method, use nameof(MyMethod).
AlwaysSyncAttribute
The field or property is always synchronized, it can not be turned off in the MultiplayerIsEasyComponent.
AvoidSyncAttribute
The field, property, class or struct can not be synchronized and it is not shown in the MultiplayerIsEasyComponent.
ConnectionRequest
A client that wants to join the game. The server receives it in MultiplayerIsEasyAPI.ConnectionApproval to decide if the client can join (after the password and the version were checked).
Properties
AddressThe IP address and port of the client.
DataThe text that the client set in
MultiplayerIsEasyAPI.ConnectionDatabefore connecting, for example the name of the player.RejectMessageThe message that the client receives if the connection is rejected.
DisconnectReason
Why a connection was closed.
Fields
NoneThere is no reason, the connection is still open.
DisconnectedThe local game closed the connection, for example with
MultiplayerIsEasyAPI.Stop(). On the server it means that the client left the game.ServerShutdownThe server was stopped.
TimeoutNothing was received from the other side for longer than the timeout of the manager.
ConnectionFailedThe server could not be reached. Check the address, the port, the firewall and that the server is running.
ServerFullThe server already has the maximum number of clients.
WrongPasswordThe password of the client is not the password of the server.
VersionMismatchThe client and the server are different builds: different version of the asset, of the game (Application.version) or different network prefabs or synchronized fields.
RejectedThe connection approval callback of the server rejected the client.
KickedThe server disconnected the client.
ProtocolErrorInvalid data was received, the connection was closed to protect the game.
AutoStartMode
How the manager starts when the game starts.
Fields
NoneIt does not start, call
MultiplayerIsEasyAPI.StartHost, StartServer or StartClient (or use the MultiplayerIsEasyHUD).HostStarts as host: server and client at the same time.
ServerStarts as a dedicated server (without a local player).
ClientConnects as a client to the address and port of the manager.
LogLevel
Which messages of the asset are shown in the console.
Fields
AllEverything, including connections and disconnections.
WarningsWarnings and errors.
ErrorsOnly errors.
NoneNothing.
NetworkStatistics
Statistics of the network traffic of the local game.
Properties
RoundTripTimeRound trip time in milliseconds: on a client the time to the server and back, on the server the average of the clients.
BytesSentTotal bytes sent since the start of the session.
BytesReceivedTotal bytes received since the start of the session.
BytesSentPerSecondBytes sent during the last second.
BytesReceivedPerSecondBytes received during the last second.
PacketsSentTotal packets sent since the start of the session.
PacketsReceivedTotal packets received since the start of the session.
ResentMessagesReliable messages that had to be sent again because they were lost.
ConnectionsNumber of connections: on the server the remote clients, on a client 1 when it is connected.
Contact
For questions, problems or suggestions, write to zedgeincorporation@gmail.com, in English or Spanish.