Introduction
Photon Unity Networking (PUN) is a Unity package for multiplayer games.
Flexible matchmaking gets your players into rooms where objects can be synced over the network.
RPCs, Custom Properties or "low level" Photon events are just some of the features.
The fast and (optionally) reliable communication is done through dedicated Photon server(s), so clients don't need to connect one to one.
PUN exports to basically all platforms supported by Unity and has two options:
PUN FREE
No-cost package with various demos, pre-made scripts and reference documentation. Exports to basically all platforms.
PUN PLUS
Same content as PUN FREE, plus a 100 concurrent user plan for the Photon Cloud (approx. 40k MAU, valid 12 months).
Join our discord server to chat with the community or one of our team members when available.
PUN's Structure
Usually, you don't have to mind the structure of the PUN package but just for the overview, here's how things stack up. The PUN package wraps up three layers of APIs:
- The highest level is the PUN code, which implements Unity-specific features like networked objects, RPCs and so on.
- The second level contains the logic to work with Photon servers, do matchmaking, callbacks and such. This is the Realtime API. This can be used on it's own already. You will notice a lot of overlap of topics between PUN and the Realtime API (a.k.a. LoadBalancing API) but that's fine.
- The lowest level is made up of DLL files, which contain the de/serialization, protocols and such.
Get Started
To get the best out of PUN, you will need to do some programming.
This page shows several important code snippets as an overview.
To get properly started, work through the "PUN Basics Tutorial".
Connect and Callbacks
ConnectUsingSettings
gets you online in no time: It grabs all important settings from the PhotonServerSettings
asset and off you go.
C#
PhotonNetwork.ConnectUsingSettings();
PUN uses callbacks to let you know when the client established the connection, joined a room, etc..
For example: IConnectionCallbacks.OnConnectedToMaster
.
For convenience, PUN has the MonoBehaviourPunCallbacks
MonoBehaviour. It implements important callback-interfaces and registers itself automatically, so you can inherit it and just override specific callback-methods.
C#
// ...
public class YourClass : MonoBehaviourPunCallbacks
{
// ...
public override void OnConnectedToMaster()
{
Debug.Log("OnConnectedToMaster() was called by PUN.");
PhotonNetwork.JoinRandomRoom();
}
// ...
}
// ...
Alternatively implement IConnectionCallbacks
in any class and register instances for callbacks via PhotonNetwork.AddCallbackTarget
.
Matchmaking
Within OnConnectedToMaster
you could try to join an existing room or create your own.
The following code snippets show possible method calls to start or join games.
C#
// Join room "someRoom"
PhotonNetwork.JoinRoom("someRoom");
//Fails if "someRoom" is not existing, closed or full. Error callback: IMatchmakingCallbacks.OnJoinRoomFailed
C#
// Tries to join any random game:
PhotonNetwork.JoinRandomRoom();
//Fails if there are no open games. Error callback: IMatchmakingCallbacks.OnJoinRandomFailed
C#
// Create this room.
PhotonNetwork.CreateRoom("MyMatch");
// Fails if "MyMatch" room already exists and calls: IMatchmakingCallbacks.OnCreateRoomFailed
When friends want to play together and have a way to communicate outside of PUN (e.g. with Photon Chat, Facebook), they can make up a room name and use JoinOrCreateRoom
.
If nobody else should be matched into this room, make it invisible for matchmaking:
C#
RoomOptions roomOptions = new RoomOptions();
roomOptions.IsVisible = false;
roomOptions.MaxPlayers = 4;
PhotonNetwork.JoinOrCreateRoom(nameEveryFriendKnows, roomOptions, TypedLobby.Default);
With JoinOrCreateRoom
, the room gets created on demand, so it doesn't matter who is first.
If it's full, IMatchmakingCallbacks.OnJoinRoomFailed
gets called (if you implemented and registered it somewhere).
Read more about matchmaking in our guide.
Game Logic
GameObjects can be instantiated as "networked GameObjects" with a PhotonView
component. It identifies the object and the owner (or controller). The player who's in control, updates everyone else.
Typically, you would add a PhotonView
to a prefab, select the Observed
component for it and use PhotonNetwork.Instantiate
to create an instance.
The observed component of a PhotonView
is in charge of writing (and reading) the state of the networked object several times a second. To do so, a script must implement IPunObservable
, which defines OnPhotonSerializeView
. It looks like this:
C#
// used as Observed component in a PhotonView, this only reads/writes the position
public void OnPhotonSerializeView(PhotonStream stream, PhotonMessageInfo info)
{
if (stream.IsWriting)
{
Vector3 pos = transform.localPosition;
stream.Serialize(ref pos);
}
else
{
Vector3 pos = Vector3.zero;
stream.Serialize(ref pos); // pos gets filled-in. must be used somewhere
}
}
Clients can do Remote Procedure Calls on specific networked objects for anything that happens infrequently:
C#
// defining a method that can be called by other clients:
[PunRPC]
public void OnAwakeRPC(byte myParameter)
{
//Debug.Log(string.Format("RPC: 'OnAwakeRPC' Parameter: {0} PhotonView: {1}", myParameter, this.photonView));
}
C#
// calling the RPC somewhere else
photonView.RPC("OnAwakeRPC", RpcTarget.All, (byte)1);
Independent from GameObjects, you can also send your own events:
C#
PhotonNetwork.RaiseEvent(eventCode, eventContent, raiseEventOptions, SendOptions.SendReliable);
Read more about PUN's RPCs and RaiseEvent.
Demos and Tutorials
In the PUN packages, you find several demos and useful scripts, which you can reuse and or dissect and redo.
To get properly started, take your time to read and code the "PUN Basics Tutorial".
Back to top