This document is about: PUN 2

PUN Classic (v1), PUN 2 and Bolt are in maintenance mode. PUN 2 will support Unity 2019 to 2022, but no new features will be added. Of course all your PUN & Bolt projects will continue to work and run with the known performance in the future. For any upcoming or new projects: please switch to Photon Fusion or Quantum.

Migration Notes

PUN 2 aggregates a lot of breaking changes and updates in one package but the overall usage will be similar to PUN as you know it. It is a separate package from PUN 1.x so you can choose when to update. Also, you can go back anytime.

If you use PUN Plus (v1.x) and want to update to PUN 2, use your existing AppId with the PUN 2 Free package. All benefits carry over.

To update, it's best to completely remove PUN and do a clean install of PUN 2 to make the necessary API and logic changes. Below, you will find the biggest changes but the list may be incomplete.


  • PUN 2 now includes and makes use of the Realtime API, which is less Unity specific.
  • There are two distinct namespaces for the two layers: Photon.Pun and Photon.Realtime.
  • Best Region selection and a system for callbacks are now done in the Realtime API. The regions enum is gone.
  • Only ConnectUsingSettings() is making use of the PhotonServerSettings.
  • Many callbacks, methods and fields were renamed for various reasons. Read more here.
  • For callbacks a class has to implement an interface and register itself as interested. Read more here.
  • MonoBehaviourPunCallbacks implements most callbacks. Inherit this class and override as needed. Call base in OnEnable and OnDisable. Read more here.

API Changes

  • PhotonNetwork.autoJoinLobby and ServerSettings.JoinLobby are gone. Unless you need a lobby, don't join them.

  • PhotonNetwork.GetRoomList() is gone. You get rooms list and updates from ILobbyCallbacks.OnRoomListUpdate(List<RoomInfo> roomList) callback. You can optionally cache it, update it and clear it when needed. See snippet here.

  • PhotonNetwork.Friends is gone. You get friends list from IMatchmakingCallbacks.OnFriendListUpdate(List<FriendInfo> friendList) callback. You can optionally cache it, update it and clear it when needed.

  • PhotonNetwork.LobbyStatistics is gone. When enabled, you can get lobby statistics list from ILobbyCallbacks.OnLobbyStatisticsUpdate(List<TypedLobbyInfo> lobbyStatistics) callback. You can optionally cache it, update it and clear it when needed.

  • PhotonNetwork.connecting is gone.

  • PhotonNetwork.connectionState is gone.

  • PhotonNetwork.isNonMasterClientInRoom is gone.

  • PhotonNetwork.autoCleanUpPlayerObjects is gone. In PUN2 this setting is no longer global but per room. You can set it during room creation via RoomOptions.CleanupCacheOnLeave. When joined to a room you can get it via PhotonNetwork.CurrentRoom.AutoCleanUp.

  • PhotonNetwork.networkingPeer is gone. The tasks it covered are either now handled directly in the PhotonNetwork class or in the PhotonNetwork.NetworkingClient.

  • PhotonNetwork.ConnectUsingSettings() no longer takes gameVersion parameter. Instead the AppVersion parameter set from the Unity Editor in the PhotonServerSettings, AppSettings section is used as PhotonNetwork.GameVersion. If you want to set the PhotonNetwork.GameVersion from code you could either

    • set PhotonNetwork.GameVersion just after calling PhotonNetwork.ConnectUsingSettings()
    • set PhotonNetwork.PhotonServerSettings.AppSettings.AppVersion before calling PhotonNetwork.ConnectUsingSettings()
  • Only ConnectUsingSettings() is making use of PhotonServerSettings. When using the other connect-methods, the app needs to set AppId and other values manually (and the settings won't override those values).

  • ServerSettings.EnableLobbyStatistics is moved to ServerSettings.AppSettings.EnableLobbyStatistics.

  • ServerSettings.AppID is moved to ServerSettings.AppSettings.AppIdRealtime.

  • ServerSettings.VoiceAppID is moved to ServerSettings.AppSettings.AppIdVoice.

  • ServerSettings.ChatAppID is moved to ServerSettings.AppSettings.AppIdChat.

  • ServerSettings.NetworkLogging is moved to ServerSettings.AppSettings.NetworkLogging.

  • ServerSettings.ServerAddress is moved to ServerSettings.AppSettings.Server.

  • ServerSettings.ServerPort is moved to ServerSettings.AppSettings.Port.

  • ServerSettings.Protocol is moved to ServerSettings.AppSettings.Protocol.

  • In PUN2, the UserId will no longer be set to the Nickname in case the former was not set. This used to be the case for PUN1.

  • PhotonNetwork.LoadLevelAsync() is gone. PhotonNetwork.LoadLevel is always async by default and by design in PUN2. To get the level loading progress, use PhotonNetwork.LevelLoadingProgress.

  • PhotonNetwork.PhotonServerSettings.UseMyServer(server, port, app) is gone, it can be replaced with:


    PhotonNetwork.PhotonServerSettings.AppSettings.Server = server;
    PhotonNetwork.PhotonServerSettings.AppSettings.Port = port;
    PhotonNetwork.PhotonServerSettings.AppSettings.RealtimeAppId = app; // either AppId or "master" or don't set anything

    Also, if you use Photon Server v4: PhotonNetwork.PhotonServerSettings.AppSettings.UserNameServer = false; If you use Photon Server v5 (and use the Name Server, which is recommended): PhotonNetwork.PhotonServerSettings.AppSettings.UserNameServer = true;

Namespace Changes

  • RoomOptions is now in the Photon.Realtime namespace
  • AuthenticationValues is now in the Photon.Realtime namespace
  • RoomInfo is now in the Photon.Realtime namespace
  • Room is now in the Photon.Realtime namespace
  • FriendInfo is now in the Photon.Realtime namespace
  • TypedLobbyInfo is now in the Photon.Realtime namespace
  • TypedLobby is now in the Photon.Realtime namespace
  • LobbyType is now in the Photon.Realtime namespace
  • RaiseEventOptions is now in the Photon.Realtime namespace
  • WebRpcResponse is now in the Photon.Realtime namespace
  • IPunObservable is now Photon.Pun namespace


camelCase to PascalCase

Public fields and properties:

  • photonView.isMine is now photonView.IsMine
  • photonView.owner is now photonView.Owner
  • photonView.instantiationData is now photonView.InstantiationData
  • PhotonNetwork.automaticallySyncScene is now PhotonNetwork.AutomaticallySyncScene
  • PhotonNetwork.gameVersion is now PhotonNetwork.GameVersion
  • PhotonNetwork.masterClient is now PhotonNetwork.MasterClient
  • PhotonNetwork.isMasterClient is now PhotonNetwork.IsMasterClient
  • PhotonNetwork.inRoom is now PhotonNetwork.InRoom
  • PhotonNetwork.isMessageQueueRunning is now PhotonNetwork.IsMessageQueueRunning
  • PhotonNetwork.offlineMode is now PhotonNetwork.OfflineMode
  • PhotonNetwork.countOfPlayersOnMaster is now PhotonNetwork.CountOfPlayersOnMaster
  • PhotonNetwork.countOfPlayersInRooms is now PhotonNetwork.CountOfPlayersInRooms
  • PhotonNetwork.countOfPlayers is now PhotonNetwork.CountOfPlayers
  • PhotonNetwork.countOfRooms is now PhotonNetwork.CountOfRooms
  • PhotonNetwork.sendRate is now PhotonNetwork.SendRate
  • PhotonNetwork.time is now PhotonNetwork.Time
  • PhotonNetwork.playerList is now PhotonNetwork.PlayerList
  • PhotonNetwork.precisionForVectorSynchronization is now PhotonNetwork.PrecisionForVectorSynchronization
  • PhotonNetwork.precisionForQuaternionSynchronization is now PhotonNetwork.PrecisionForQuaternionSynchronization
  • PhotonNetwork.precisionForFloatSynchronization is now PhotonNetwork.PrecisionForFloatSynchronization
  • PhotonStream.isWriting is now PhotonStream.IsWriting
  • PhotonStream.isReading is now PhotonStream.IsReading
  • RoomOptions.cleanUpCacheOnLeave is now RoomOptions.CleanupCacheOnLeave
  • RoomOptions.publishUserId is now RoomOptions.PublishUserId
  • RoomOptions.suppressRoomEvents is now RoomOptions.SuppressRoomEvents


  • PhotonNetwork.connected is now PhotonNetwork.IsConnected
  • PhotonNetwork.connectedAndReady is now PhotonNetwork.IsConnectedAndReady
  • PhotonNetwork.networkingPeer is now PhotonNetwork.NetworkingClient
  • PhotonNetwork.connectionStateDetailed is now PhotonNetwork.NetworkClientState
  • PhotonNetwork.playerName is now PhotonNetwork.NickName
  • is now PhotonNetwork.CurrentRoom
  • PhotonNetwork.lobby is now PhotonNetwork.CurrentLobby
  • PhotonNetwork.player is now PhotonNetwork.LocalPlayer
  • PhotonNetwork.insideLobby is now PhotonNetwork.InLobby
  • PhotonNetwork.otherPlayers is now PhotonNetwork.PlayerListOthers
  • PhotonNetwork.sendRateOnSerialize is now PhotonNetwork.SerializationRate
  • PhotonNetwork.versionPUN is now PhotonNetwork.PunVersion
  • PhotonTargets enum is now Photon.Pun.RpcTarget
  • PhotonPlayer class is now Photon.Realtime.Player (constructor is no longer public)
  • PhotonPlayer.ID is now Photon.Realtime.Player.ActorNumber

Callbacks Changes

You can read more about new callbacks on this page.

  • All callback interfaces except IPunInstantiateMagicCallback must be registered and unregistered.
    Call PhotonNetwork.AddCallbackTarget(this) and PhotonNetwork.RemoveCallbackTarget(this) (likely within OnEnable() and OnDisable() respectivly)

  • Replace Photon.PunBehaviour with MonoBehaviourPunCallbacks.
    Call the base class methods in overrides of OnEnable() and OnDisable() for MonoBehaviourPunCallbacks

  • PhotonNetwork.OnEventCall is gone.
    You have two options:

    1. use PhotonNetwork.NetworkingClient.EventReceived(EventData) instead.
    2. use IOnEventCallback.OnEvent(EventData).

    In PUN2, events callback signature changed but you can get what you need from EventData. Also, events callback will be triggered for all events and not only custom events (custom event code < 200).

  • By default, setting properties for actor or room properties will not take effect on the sender/setter client (actor that sets the properties) immediately when joined to an online room unlike what it used to be in PUN Classic. Now, instead, the sender/setter client (actor that sets the properties) will wait for the server event PropertiesChanged to apply/set changes locally. So you need to wait until OnPlayerPropertiesUpdate or OnRoomPropertiesUpdate callbacks are triggered for the local client in order to access them. The new behaviour is due to the introduction of the new room option flag roomOptions.BroadcastPropsChangeToAll which is set to true by default. The reason behind this is that properties can easily go out of synchronization if we set them locally first and then send the request to do so on the server and for other actors in the room. The latter might fail and we may end up with properties of the sender/setter client (actor that sets the properties) different locally from what's on the server or on other clients. If you want to have the old behaviour (set properties locally before sending the request to the server to synchronize them) set roomOptions.BroadcastPropsChangeToAll to false before creating rooms. But we highly recommend against doing this.

  • PUN2 will not trigger OnRoomPropertiesUpdated or OnPlayerPropertiesUpdated callbacks unless those are changed via SetProperties calls. In PUN2, when entering rooms (after creating, joining or re joining rooms) OnPlayerPropertiesUpdate or OnRoomPropertiesUpdate callbacks will not be triggered for initialized properties. You can access initial values via PhotonNetwork.CurrentRoom.CustomProperties (or other class properties of PhotonNetwork.CurrentRoom, like IsOpen, IsVisible, MaxPlayers, etc.) or PhotonNetwork.LocalPlayer.CustomProperties.

In the table below, method parameters are shown only when method signatures are different between PUN1 and PUN2.
PUN 1 (Callback) PUN 2 (Interface | Callback)
OnConnectedToPhoton IConnectionCallbacks OnConnected
OnFailedToConnectToPhoton() IConnectionCallbacks OnDisconnected(DisconnectCause)
OnConnectionFail() IConnectionCallbacks OnDisconnected(DisconnectCause)
OnDisconnectedFromPhoton() IConnectionCallbacks OnDisconnected(DisconnectCause)
OnConnectedToMaster IConnectionCallbacks OnConnectedToMaster
OnPhotonMaxCccuReached() IConnectionCallbacks OnDisconnected(DisconnectCause)
OnCustomAuthenticationFailed IConnectionCallbacks OnCustomAuthenticationFailed
OnCustomAuthenticationResponse IConnectionCallbacks OnCustomAuthenticationResponse
OnMasterClientSwitched(PhotonPlayer) IInRoomCallbacks OnMasterClientSwitched(Player)
OnPhotonPlayerConnected(PhotonPlayer) IInRoomCallbacks OnPlayerEnteredRoom(Player)
OnPhotonPlayerDisconnected(PhotonPlayer) IInRoomCallbacks OnPlayerLeftRoom(Player)
OnPhotonPlayerActivityChanged(PhotonPlayer) IInRoomCallbacks OnPlayerEnteredRoom(Player)
OnPhotonCustomRoomPropertiesChanged IInRoomCallbacks OnRoomPropertiesUpdate
OnPhotonPlayerPropertiesChanged(object[]) IInRoomCallbacks OnPlayerPropertiesUpdate(Player, Hashtable)
OnJoinedLobby ILobbyCallbacks OnJoinedLobby
OnLeftLobby ILobbyCallbacks OnLeftLobby
OnReceivedRoomListUpdate() ILobbyCallbacks OnRoomListUpdate(List<RoomInfo>)
OnLobbyStatisticsUpdate() ILobbyCallbacks OnLobbyStatisticsUpdate(List<TypedLobbyInfo>)
OnLeftRoom IMatchmakingCallbacks OnLeftRoom
OnPhotonCreateRoomFailed(object[]) IMatchmakingCallbacks OnCreateRoomFailed(short, string)
OnPhotonJoinRoomFailed(object[]) IMatchmakingCallbacks OnJoinRoomFailed(short, string)
OnCreatedRoom IMatchmakingCallbacks OnCreatedRoom
OnJoinedRoom IMatchmakingCallbacks OnJoinedRoom
OnPhotonRandomJoinFailed(object[]) IMatchmakingCallbacks OnJoinRandomFailed(short, string)
OnUpdatedFriendList() IMatchmakingCallbacks OnFriendListUpdate(List<FriendInfo>)
- IOnEventCallbackOnEvent(EventData)
OnPhotonInstantiate IPunInstantiateMagicCallback OnPhotonInstantiate
OnPhotonSerializeView IPunObservable OnPhotonSerializeView
OnOwnershipRequest(object[]) IPunOwnershipCallbacks OnOwnershipRequest(PhotonView, Player)
OnOwnershipTransfered(object[]) IPunOwnershipCallbacks OnOwnershipTransfered(PhotonView, Player)
OnWebRpcResponse IWebRpcCallback OnWebRpcResponse
Back to top