This page is a work in progress and could be pending updates.

Coming From PUN

Introduction

This article discusses how to get into Fusion when coming from a PUN background; the focus is on object synchronization and gameplay.

While PUN is a vastly successful and easy to use networking solution, it shows its age and inadequacies to handle modern multiplayer games aspects such as higher player counts, precise replication of player actions and handling of authority. Fusion is just as easy to use and should be preferred for most projects.

Back To Top

Differences

There are some differences to look out for when coming from PUN.

Fusion instantiates a Runner per player and it has to be setup in some scene. To do so, the context-menu of the Hierarchy panel has a Fusion submenu with useful shortcuts to setup scenes.

Fusion can run multiple Runner instances in one process, which is mostly for testing and debugging. Helper panels in the Editor let you chose which instance is visible and gets input.

When the Editor runs multiple peers at the same time, it will reload the current scene when it starts. Game logic may have to be adjusted to support this. S standalone build can easily connect with the Editor, as in PUN.

Many APIs in PUN were available via the PhotonNetwork class. Fusion has a Runner per instance instead. Any class inheriting from SimulationObject or NetworkObject have access to the Runner and Object members, so accessing the Fusion APIs is just as easy as in PUN.

Where PUN only offers "distributed" authority, Fusion supports running as Dedicated Server, Client Hosted and Shared Mode. The Shared Mode is similar to PUN and authority of Networked objects is distributed to the players. Scene objects are controlled by one player automatically.

Where PUN only has the concept of control for objects, Fusion breaks down authority into state authority and input authority (unless Shared Mode is used).

Scripts in PUN usually only check photonView.IsMine to determine if a client controls the object. Fusion keeps track of Object.HasStateAuthority and Object.HasInputAuthority separately. Ports from PUN should use the Shared Mode of Fusion and check HasStateAuthority.

In PUN, the Player.ActorNumber goes up for every new player. In Fusion, the PlayerRef starts at 0 and goes up to MaxPlayers - 1. If there is a host for a game, that player will always get MaxPlayers - 1 as PlayerRef value.

Fusion needs to know the scenes of a project. Scenes can be arranged in the project build setup and then imported from there.

Back To Top

Similarities

While the expectation may be that Fusion is vastly different from PUN, many ideas actually carry over.

A key element in PUN is the PhotonView which has a direct equivalent called NetworkObject. As in PUN, the NetworkObject is just an identifier and relies on additional components to provide the desired behaviour.

Fusion has replacements for the common components: For example, a PhotonRigidbodyView can be replaced with a NetworkRigidbody, the PhotonTransformView becomes a NetworkTransform. Both are available as 2D variant, just as in PUN.

The PhotonAnimatorView can be replaced with a NetworkMecanimAnimator. For controlling characters specifically, Fusion has a comprehensive NetworkCharacterController which PUN does not offer.

The individual settings of components are different - in most cases the default values are fine to start. All components on NetworkObjects and children are found automatically. Fusion fully supports having multiple NetworkObjects in a hierarchy, where needed.

As in PUN, NetworkObjects can be placed in a scene or instantiated at runtime. In Fusion, call Runner.Spawn() instead of PhotonNetwork.Instantiate(). To load scenes, replace PhotonNetwork.LoadLevel() with Runner.SetActiveScene().

Other important classes in PUN are the MonoBehaviourPun and MonoBehaviourPunCallbacks. In Fusion, scripts inherit from NetworkBehaviour to write game logic and keep state. Scripts can inherit the SimulationBehaviour, if they will not contain game state. Where PUN called OnPhotonInstantiate(), Fusion uses the Spawned() callback to initialize network scripts.

While Custom Properties in PUN were Hashtables with setter methods, Fusion synchronizes plain C# properties instead: As part of a NetworkBehaviour, auto-implemented properties just need a [Networked] attribute to become part of the game state. Only the authority of an object can change the values and they are automatically replicated over the network, which means less potential for cheating.

Remote procedure calls (RPCs) are also supported and taken to a new level: Put the attribute [RPC] on a method and call it as it you call a local method - Fusion will convert the calls to work over the network.

Back To Top

Reference Table

PUN Fusion
PhotonNetwork SimulationBehaviour.Runner and SimulationBehaviour.Object
MonoBehaviourPunCallbacks SimulationBehaviour and NetworkBehaviour
PhotonNetwork.AddCallbackTarget(this) N/A (automatic)
PhotonNetwork.Instantiate() Runner.Spawn()
PhotonView NetworkObject
IPunObservable.OnPhotonSerializeView() C# auto-implemented properties and Input Sync
PhotonTransformView NetworkTransform
PhotonRigidbodyView NetworkRigidbody
PhotonAnimatorView NetworkMecanimAnimator
N/A NetworkCharacterController
[PunRPC] [RPC]
PhotonNetwork.LoadLevel() Runner.SetActiveScene()


To Document Top