This document is about: PUN 1
SWITCH TO

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.

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.

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.

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.

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.

Back to top