Optimization Tips

Performance Optimization

Pool Objects for Instantiation

PUN has a built-in option to instantiate objects from a pool, rather than from a loaded resource (which is kept in-memory to speed up things). Read Using the PrefabPool in the Instantiation doc page.

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 serialized immediately but not sent to the socket right away. Instead it's queued until SendOutgoingCommands() gets called. This way, Photon aggregates messages into fewer datagrams to optimize traffic.

To avoid the local lag on demand, your logic should have a trigger to call SendOutgoingCommands() in a LateUpdate(), when needed. Doing this on demand is OK.

Network Traffic Optimization

Compact Serialization

You can optimize traffic quite a bit by having a closer look at what you are sending and how. This can be done later in the development, without a lot of extra hassle. As usual with optimization, start with the most frequently sent messages first.

Often, values and objects are sent with more values than needed to share the state. If your character can't scale, don't sync scale! If your character is never leaning to a side, rotation could be a single float. Actually, a byte may be enough for the rotation without much precision loss. This is fine for non-physical objects.

In general, have a look at what you do in OnPhotonSerializeView and RPCs. You can send a variable amount of values per OnPhotonSerializeView. Sending compact byte arrays is often leaner than registering and sending a lot of Custom Types.

There are some tools that may make your life easier without much hassle. Have a look at the Network Transform Sync package, which provides advanced Transform synchronization with optimized traffic. The Transform Crusher - Free is an option if you just streamline what you send.

Another library that can help with serialization is NetStack. It comes with various other useful features, too.

Network Culling and Interest Groups

Another technique to save quite some bandwidth is "Network Culling". The team of M2H described their approach here. See Interest Groups

To Document Top