UNET HLAPI guide

In order to use any of the unity networking HLAPI features you must include UnityEngine.Networking and inherit from NetworkBehaviour.
UnityEngine.Networking;

1
2
3
UnityEngine.Networking;

public class YourClass: NetworkBehaviour { }

To call Command or ClientRPC, the object has to have authority and prefix Cmd/Rpc as in examples below. Keep in mind that only one player can have authority over a single object.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[Command]
public void CmdYourName() {}
//this code will get called only by client
//and runs only on server
//only clients with authority can call this
//if called from server it will throw an error

[Command]
public void CmdSendGameObject(GameObject go) {}
//you can pass a gameobject as argument
// though, it will only work if the object
// has a NetworkIdentity

public override void OnStartLocalPlayer() {}
//Use this instead of Start() if you need to
//execute something only on objets with authority

//Note that you might see "lag" for you commands even
//when using local host. Default behavior is to sync
//in tick of 20ms~. You can work around this by using
//state update channel.
1
2
3
4
5
6
7
8
[ClientRpc]
public void RpcYourCall()
{
//can only get called from server and runs on
//clients gets sent to every other connected player
//server does not count as a player
//therefore the code does not run on server
}

The arguments passed to commands and ClientRpc calls are serialized and sent over the network. These arguments can:

1
2
3
4
5
6
7
8
basic types (byte, int, float, string, UInt64, etc)
arrays of basic types
structs containing allowable types
built-in unity math types (Vector3, Quaternion, etc)
NetworkIdentity
NetworkInstanceId
NetworkHash128
GameObject with a NetworkIdentity component attached
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
//These can be useful for function calls such as
//Start(), Update(), etc...
//in order to implement functionality without writing code

[Client]
void Start()
{
//code inside this function gets called only
//when called on client if called on server it
// will throw a warning stating it has been called
}

[ClientCallback]
void Start()
{
//acts exactly as [Client] attribute, except that
// it does not throw error
}

[Server]
void Start()
{
//code inside this function gets called
//only when called on server
//if called on client it will throw a warning
// stating it has been called
}

[ServerCallback]
void Start()
{
//acts exactly as [Server] attribute
//except that it does not throw error
}

If you want to call a function only on one particular client you should use the [TargetRpc] attribute. By default it must have NetworkConnection argument. You can get the NetworkConnection to client by using NetworkIdentity.connectionToClient

1
2
3
4
5
6
7
//can only get called from server
[TargetRpc]
void TargetGiveJob(NetworkConnection target)
{
//This will get called only on one client
//which is the NetworkConnection parameter
}
1
2
3
4
5
6
7
8
9
10
11
12
13
//channel variable sets the default channel
//for every SyncVar,Cmd, etc..
//channel numbering starts from 0 and is
//taken straight from NetworkManager
//channel can be set using the NetworkManager
//(Image attached at end of post)
//sendInterval is the value at which your
//syncvars, commands will get updated
//for example if you update your syncvar
//10times a sek and interval is .2f
//it will update only 5times per sek (every .2f)
[NetworkSettings(channel=1,sendInterval=0.2f)]
class MyScript : NetworkBehaviour {}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
// you can define a SyncVar like this:
[SyncVar]
int health = 100;

//variables will have their values sychronized
//from the server to clients
//changing values on client will not sync them
//neither to server neither to other clients
//neither will an error be printed
//values will only be synced if changed

//you can also add attach a function to a syncvar
[SyncVar(hook = "your_function")]
int health;

//hook functions must take the same argument type
// as the synced var
void your_function(int newHealth)
{
//it must be set to new value by script
health = newHealth;
//do something else, like update UI values
//hooks will only get called on clients!
//does not get called on server
}

/*
Note that setting a SyncVar member variable
inside a property setter function does not cause
it to be dirtied. Trying to do this
will cause a compile time warning.

There can be up to 32 SyncVars on a
single NetworkBehaviour script
this includes SyncLists.

The state of SyncVars is applied to objects on
clients before OnStartClient()
is called, so the state of the object is guaranteed
to be up-to-date insideOnStartClient().
*/

You can mimic SyncVar behavior for these types of lists:
SyncListString, SyncListFloat, SyncListInt, SyncListUInt, SyncListBool

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
SyncListBool DrunkList = new SyncListBool();

//every SyncList has to include these arguments
void DrunkChanged(SyncListBool.Operation op, int itemIndex)
{
//gets called only on clients
//Operation returns an enum more about this in
//http://docs.unity3d.com/ScriptReference/Networking.SyncList_1.Operation.html
//int value is the exact index of the value that
// has been added/changed
//the value passed starts from 0
}

void Awake()
{
//setting Callback function for the SyncList
DrunkList.Callback = DrunkChanged;
//DrunkList.Add(true); -> will throw an error
//SyncVars are not initialized until
//Start() is called
}

You can sync structs as well. Although they will be updated as a ‘whole’ instead of single variables inside them. Usage below:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public struct Player
{
public int number;
public string name;
};

public class PlayerStructClass : SyncListStruct<Player> { }
PlayerStructClass SyncStructPlayer = new PlayerStructClass();

void PlayerChanged(SyncListStruct<Player>.Operation op, int itemIndex)
{
Debug.Log("buf changed:" + op);
}

void Start()
{
SyncStructPlayer.Callback = PlayerChanged;
}

If you want to sync an Instantiation of GameObject then Spawn is what you are searching for:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//prefab reference
//must be added to NetworkManager
//must have NetworkIdentity on parent object
public GameObject fab;

[Server]
public void InstantiateAndSpawn()
{
//Instantiates an object locally
GameObject go = (GameObject)Instantiate(fab);
//spawns the same gameObject for
//every connected client
NetworkServer.Spawn(go);
//once an object is destroyed on server it
//is then synced to clients
}

There are helper functions to find networked objects that you know the NetworkInstanceId.

1
2
3
4
5
6
7
//find object by their GetComponent<NetworkIdentity>().netId;
ClientScene.FindLocalObject(id);
NetworkServer.FindLocalObject(id);

//You can change the scene for all players
//calling this from the server
ServerChangeScene(sceneName);

Offline scene should be the connection scene where you have the host/connect.
Online scene is the scene that your players will transition to after starting.

  • You can only add scenes that have been added to the build settings!

HLAPI components

NetworkManager – manages connecting, starting server and players in order to wire UI, you should wrap the calls in public void methods. Otherwise you can just use the NetworkManagerHUD component, just keep in mind you have almost no control over it.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
using UnityEngine;
using UnityEngine.Networking;

public class NetworkingManager : NetworkManager
{
public void StartHost_UI()
{
base.StartHost();
}

public void StartClient_UI()
{
base.StartClient();
}
}

NetworkIdentity – all networked components should have this In the inspector it has two bool values Server Only -> this will make the object live only on the server (useful for manager, like spawning enemies) Local Player Authority -> gives authority to the local player, you can’t call commands unless this is selected

NetworkTransform – used for syncing transform. Any changes on the client side will not affect server unless local player authority is set The component has many issues and you should keep that in mind. When syncing physics you should move object using Physics, moving the transform will not sync position. Interpolation does not work as of right now(bug) You can have only one NetworkTransform per root game object To sync transorm of child objects use NetworkTransformChild NetworkTransformVisualizer – is supposed to visualise interpolation, but since interpolation is broken it doesn’t have any use right now.

NetworkAnimator – will sync the network animator states

NetworkIdentity – all networked components should have this In the inspector it has two bool values Server Only -> this will make the object live only on the server (useful for manager, like spawning enemies) Local Player Authority -> gives authority to the local player, you can’t call commands unless this is selected

NetworkTransform – used for syncing transform. Any changes on the client side will not affect server unless local player authority is set The component has many issues and you should keep that in mind. When syncing physics you should move object using Physics, moving the transform will not sync position. Interpolation does not work as of right now(bug) You can have only one NetworkTransform per root game object To sync transorm of child objects use NetworkTransformChild

NetworkTransformVisualizer – is supposed to visualise interpolation, but since interpolation is broken it doesn’t have any use right now.

You should also read the following documentation page on UNET concepts:
http://docs.unity3d.com/Manual/UNetConcepts.html
Qos channel explanations:
http://docs.unity3d.com/ScriptReference/Networking.QosType.html