PUN Classic (also called PUN1) is the original and first major version of PUN. It is now replaced by PUN2 which is refactored and enhanced. We highly recommend starting new projects with PUN2 and if possible migrating existing ones from PUN1 to PUN2 by following our "Migration Notes". PUN Classic will be maintained for the coming months. We will fix important bugs and support new Unity versions but new features will be added only to PUN2.

Optimization Tips

Limit And Cache Callback Targets

For convenience, PUN callbacks can be implemented in any MonoBehaviour, on any GameObject and without registering any. Often that's not a problem, as these callbacks are infrequent (except maybe Custom Property updates).

Internally, Unity's SendMessage is used to dispatch callbacks and that can affect your performance. Probably even worse, FindObjectsOfType() is needed to find the components, which may (or may not) implement the callbacks.

With PhotonNetwork.SendMonoMessageTargets, you can define which GameObjects get called at all. With PhotonNetwork.CacheSendMonoMessageTargets(Type t), you can setup the SendMonoMessageTargets by defining which type of Component should be the target.

You can update the SendMonoMessageTargets as needed. Anything will be quicker than the default brute-force approach.

Back To Top

OnPhotonSerializeView And IPunObservable

When a PhotonView observes scripts, OnPhotonSerializeView gets called multiple times per second. By default, a PhotonView uses reflection and caching to find and Invoke the OnPhotonSerializeView implementations on components.

You can optimize calls of OnPhotonSerializeView by implementing the interface IPunObservable with your MonoBehaviours.

Back To Top

Cache RPC Targets

In some cases, you might use a lot of RPCs in your game. Any Component on the target GameObject may implement RPCs, so PUN will use reflection to find the fitting methods. Of course, this is expensive and even wasteful, if the components don't change.

By default, PUN caches a MethodInfo list per Type of script. It does not cache which MonoBehaviours are on the GameObject as potential target.

You can set PhotonNetwork.UseRpcMonoBehaviourCache = true, to cache the MonoBehaviours per PhotonView for RPCs. This speeds up finding the components to call. Should the scripts on a GameObject change, call photonView.RefreshRpcMonoBehaviourCache() to update as needed.

Back To Top

Avoiding Local Lag For RaiseEvent

When you call RaiseEvent, the data is not written to the socket immediately but instead it's queued until SendOutgoingCommands() gets called. This way, Photon aggregates messages into fewer datagrams and saves traffic.

To avoid the local lag, simply make RaiseEvent into a trigger to call SendOutgoingCommands() in a LateUpdate(). Doing this on demand is fully OK.

To Document Top