Coming from Pun2
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.
Fusion Modes
What is very important to understand when coming from PUN to Fusion is that PUN only offers a "distributed" authority model via a room shared by all clients.
Run Fusion in Shared Mode to allow distributed authority, similar to PUN’s model. Scene objects are controlled by one player automatically. Most concepts that exist in PUN are transferable to Fusion Shared mode but NOT to Fusion Server / Host mode.
This page explains how to migrate your PUN knowledge to Fusion Shared Mode. However, Host / Server Mode might be a better option depending on the application.
Differences
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() |
Connection and matchmaking
The core concepts of matchmaking remain the same between PUN and Fusion. Lobbies, matchmaking, rooms, properties for matchmaking etc. still exist.
Fusion uses a completely different API for the matchmaking calls which are exposed on the NetworkRunner. You can learn more about how to connect and match make using fusion here.
Where to put settings / how to replace ConnectUsingSettings, versioning
PUN stores most settings in the PhotonServerSettings
file (a Scriptable Object). It is mostly about the AppId
, server settings, protocol and logging.
In Fusion, settings are split into two files:
The PhotonAppSettings
contain the information that is used by the client to make a connection to the Photon Cloud. In most cases the only data that needs to be changed inside this config is the AppId
of the application which also can be set via the Fusion Hub.
The NetworkProjectConfig
is a detailed config exposing many configuration options for Fusion. The default configuration can be used as a starting point. Settings like tick rate, max number of players and much more.
Authentication
Fusion supports authentication providers just like PUN does. More information about this can be found on the authentication page.
Offline mode
Like PUN, Fusion has an offline mode as well. Instead of PhotonNetwork.OfflineMode
, use GameMode.Single
when calling NetworkRunner.StartGame
.
Actor Number
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.
Use Runner instead of PhotonNetwork
Many APIs in PUN were available via the PhotonNetwork
class. Fusion has a Runner per instance instead. Any class inheriting from NetworkBehaviour
have access to the Runner and Object members, so accessing the Fusion APIs is just as easy as in PUN.
The context-menu of the Hierarchy panel has a Fusion submenu with useful shortcuts to set up scenes.
Callbacks (MonoBehaviourPunCallbacks / PhotonNetwork.AddCallbackTarget(this))
Callbacks are the backbone of the PUN networking API, no matter if you wait for the connection to establish or the result of random matchmaking. In PUN, callbacks are categorized into a few interface definitions which scripts implement. At runtime these scripts have to register to get these callbacks called.
To simplify this workflow, PUN offers the MonoBehaviourPunCallbacks
class to inherit from. With this, your scripts can override the specific methods to get their callbacks.
Fusion provides most callbacks via the INetworkRunnerCallbacks
. These are session callbacks. Object specific callbacks are available on NetworkBehaviour
directly such as Spawned/Despawned
etc.
Instantiation
In Fusion, call Runner.Spawn()
instead of PhotonNetwork.Instantiate()
. To pool instances instead of using a custom IPunPrefabPool
use a INetworkObjectProvider
.
Scene objects
Scene objects work in a similar fashion in PUN and Fusion. When the scene is loaded for the first time the master client automatically takes StateAuthority
over all Scene Objects.
Manual instantiation
To replace manual instantiation from PUN in Fusion a custom INetworkPrefabSource
to provide a prefab for what is spawned is needed. Unlike PUN this does not create a specific instance of a NetworkObject but a prefab which is then instantiated by the INetworkObjectProvider
.
This is generally not recommended nor needed for most Fusion applications.
Scenes
To load scenes, replace PhotonNetwork.LoadLevel()
with Runner.SetActiveScene()
.
Multiple Scenes
In Fusion multiple scenes are supported out of the box. Runner.LoadScene
provides overloads for loading scenes additively.
PhotonView
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 behavior.
MonoBehaviourPun
MonoBehaviourPUNs
in Fusion are called NetworkBehaviours
. NetworkBehaviours
can be placed on the same GameObject
as the NetworkObject
or on child GameObjects
.
Fusion fully supports having multiple nested NetworkObjects
in a hierarchy, where needed.
PhotonTransformView
PhotonTransformView
can be replaced with NetworkTransform
. NetworkTransform
comes with better implementation and more features such as parenting out of the box.
PhotonAnimatorView -> NetworkMecanimAnimator
The PhotonAnimatorView
can be replaced with a NetworkMecanimAnimator
. The NetworkMecaimAnimator
works like PUNs version and synchronizes the animation from the client with StateAuthority
to all other clients (proxies).
CharacterController
In PUN for moving the player character a regular CharacterController
could be used. In Fusion Shared mode this is an option as well, however there is also the Simple KCC addon available which is a superior option with more features.
PhotonRigidbodyView -> NetworkRigidbody
Fusion has a network physics system that works similar to PUN. Instead of a PhotonRigidbodyView
a NetworkRigidbody3D
component is used. The client that owns the object runs the physics simulation for the rigidbody while all other clients use kinematic representations for the rigidbody to provide a view only. Physics components are also available in 2d.
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.
PhotonView.IsMine / Authority of Objects
Scripts in PUN usually only check photonView.IsMine
to determine if a client controls the object. The Fusion equivalent of photonView.IsMine
is Object.HasStateAuthority
.
Ownership transfer when players (controllers) leave
In PUN when the master client changes the new master automatically takes control over networked objects with no owner.
In Fusion when a client disconnects or leaves the room there are multiple options for handling the transfer of authority.
When IsMasterClientObject
is checked on the NetworkObject
then the StateAuthority
is automatically transferred to the new master similar to PUNs behavior.
When Destroy When State Authority Leaves
is checked the object is destroyed instead.
RPCs
Use Networked Variables where possible
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.
Networked Variables instead of Custom Properties
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.
To replace player properties simply add a NetworkBehaviour
with NetworkedProperties
to it.
To replace room properties create a scene NetworkObject
and add a NetworkBehaviour
with NetworkProperties
to it. You will have to find this object in the scene using FindObjectOfType
or a singleton pattern etc.
IPunObservable.OnPhotonSerializeView() no longer needed
OnPhotonSerializeView
is also being replaced by Networked Properties. Networked properties combine the best features of both OnPhotonSerializeView and CustomProperties. They are updated instantly with tick alignment. Only changes are synchronized, and detection change callbacks are available.
Change detection in Fusion 2
In PUN a PropertyChanged
event is fired when room or player properties are changed. In Fusion the OnChangeRender
or a ChangeDetector
can be used.
Multi Peer
Fusion can run multiple NetworkRunner
instances in one process, which is mostly for testing and debugging. Helper panels in the Editor let you choose 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. Standalone builds can easily connect with the Editor, as in PUN.
Special Cases
Shared Mode provides the same flexibility and ease of use as PUN. However, for some types of games that are more on the competitive and faster paced side, Fusion offers a dedicated server / host mode.
In this mode a server or one of the clients holds full authority over the game state. This means that this peer holds the full state and is the only peer that is allowed to modify state. Other peers can modify state in a local prediction to mask latency, but their change needs to be replicated by the server to become valid.
To figure out whether host / server mode is the better choice for your game, we suggest you have a look at the Quadrant.
- Introduction
- Fusion Modes
- Differences
- Reference Table
- Connection and matchmaking
- Where to put settings / how to replace ConnectUsingSettings, versioning
- Authentication
- Offline mode
- Actor Number
- Use Runner instead of PhotonNetwork
- Callbacks (MonoBehaviourPunCallbacks / PhotonNetwork.AddCallbackTarget(this))
- Instantiation
- Scene objects
- Manual instantiation
- Scenes
- Multiple Scenes
- PhotonView
- MonoBehaviourPun
- PhotonTransformView
- PhotonAnimatorView -> NetworkMecanimAnimator
- CharacterController
- PhotonRigidbodyView -> NetworkRigidbody
- PhotonView.IsMine / Authority of Objects
- Ownership transfer when players (controllers) leave
- RPCs
- Networked Variables instead of Custom Properties
- IPunObservable.OnPhotonSerializeView() no longer needed
- Change detection in Fusion 2
- Multi Peer
- Special Cases