Coming from Fusion 1
New Features
Fusion 2 brings a variety of new features and improvements to Fusion enhancing the API while keeping true to the core principles of Fusion. Here is a list of the most important improvements:
Interest Enter/Exit Callbacks
New IInterestEnter
and IInterestExit
callbacks have been added to Fusion. These are fired when an Network Object enters/exists a given Player's AOI regions, as well as when a player explicitly has interest in an Object added or removed (using Runner.SetPlayerAlwaysInterested()
). The callbacks are reliably computed on the server in Server, Host and Shared Mode.
Interpolation Targets
Working with interpolation targets could be difficult to get right with fusion 1 especially when parenting Network Objects. With Fusion 2 we have simplified interpolation. There are no interpolation targets anymore, instead the Transform with the NetworkTransform itself is interpolated.
NetworkTransform
There have been a few changes to NetworkTransform
. See Network Transform
Local Space
NetworkTransform
now stores its TRS data (Position/Rotation/Scale) in local space. This means:
- Child and Nested
NetworkTransform
s are MUCH more data efficient - However, Area Of Interest position is no longer valid for nested
NetworkObject
s.AreaOfInterestOverride
has been introduced to account for this, and allows aNetworkObject
to specify anotherNetworkObject
position to be used to determine Player Interest.
Sync Scale
The Transform's localScale now can optionally be synced.
Sync Parent
A NetworkObject
s parent now can optionally be synced. A valid NetworkBehaviour
must be present on the parent transform, and the NetworkTransform
must be on the root of the Network Object.
Network Physics
NetworkRigidBody
and NetworkPhysicsSimulation
have been removed from the Fusion DLL and have been replaced with the Unity Physics Addon, which currently is included in the main Fusion SDK download. The full feature set of server-only and full-prediction physics is available, and we plan to add a new forward-only mode.
Providing the physics addon via source code allows you to modify/extend it to fit your projects needs. This allows complex use cases such as VR games more flexibility when working with physics. While NetworkTransform
has removed its InterpolationTarget requirement in Fusion 2, NetworkRigidbody
still has an InterpolationTarget
property. However, an Interpolation Target is only needed for very specific use cases, and typically can be left as null
(indicating that the rigidbody transform will be be moved for interpolation).
Change Detection
A new change detection API actually allows not only to detect changes in Render
but also in FixedUpdateNetwork
to trigger gameplay logic.
Please check the Change Detection page for more information on how to use the new API.
Tick-Accurate Shared Mode
Shared Mode is now tick-accurate. This brings many improvements;
- Shared Mode interpolation is now much snappier and more accurate.
TickTimer
is now valid in Shared Mode.- Networked
Tick
values are now meaningful in Shared Mode.
Custom Interpolation
We add a new interpolation API to access data points. It gives you access of the from/to data buffers and the interpolation alpha that Fusion uses to interpolate all Networked Properties.
Lag Compensation Improvements
Lag compensation has been improved. There is no longer a need to position animated hitboxes ahead of Render to have them in the correct position. The lag compensation will automatically use the correct interpolated animation position from Render which matches what the player saw on their screen. Additionally lag compensation supports 2d uses cases and allows querying against the 2d physics scene now.
Upgrading to Fusion 2
Video
There is a video tutorial covering the upgrade process for simple Fusion projects.
Upgrade the Unity Version
Fusion 2 supports Unity 2021.x and newer versions of Unity. For projects on older Unity versions first upgrade Unity before attempting to upgrade Fusion.
Upgrading the SDK
- Before upgrading your project make sure to back up your project using a version control system software or equivalent method.
- Backup the
NetworkProjectConfig
by moving it fromAssets/Photon/Fusion/Resources/NetworkProjectConfig
toAssets/NetworkProjectConfig
. - Delete the
/Photon
folder from your project. - Download the Fusion 2 SDK and import the Unity package.
- Move
NetworkProjectConfig
back under ``Assets/Photon/Fusion/Resources/NetworkProjectConfig`. - Fusion 2 needs a separate App Id than Fusion 1 projects to work. Create a new AppId here and select Fusion 2 while creating. Insert the new AppId under
Fusion > Fusion Hub
in Unity. - Open
/Packages/manifest.json
and replace the existing addressable package with"com.unity.addressables": "1.21.12"
(or add new if Addressables are not installed). Save the file.
After you are done importing the package there will be many errors in the console. These need to be manually corrected by upgrading the API.
API Changes
Simple API Changes
Previous API | New API |
---|---|
(int)PlayerRef | PlayerRef.PlayerId |
PlayerRef.IsValid | PlayerRef.IsRealPlayer |
(int)SceneRef | SceneRef.FromIndex |
NetworkObject.NetworkGuid | NetworkObject.NetworkTypeId |
INetworkObjectPool | INetworkObjectProvider. |
NetworkTransform/NetworkTRSP.TeleportToPosition() | NetworkTransform.Teleport() |
Runner.Config.DefaultPlayers | Runner.Config.Simulation.PlayerCount |
[Accuracy] | Remove the attribute. No replacment. |
NetworkRunner.IsVisible | NetworkRunner.GetVisible() and SetVisible() |
Runner.SimulationConfig.Topology | Runner.Topology |
NetworkCharacterControllerPrototype | NetworkCharacterController |
Runner.Simulation.X (Runner.Simulation.Tick) | Runner.X (Runner.Tick) |
Runner.MultiplePeerUnityScene | Runner.SimulationUnityScene |
Runner.SetActiveScene | Runner.LoadScene (must only be called on host/master client) |
RunnerVisibilityNodes | RunnerEnableVisibility |
NetworkObjectPool
The pooling API has changed significantly to allow for asynchronous loads.
INetworkObjectPool
has been renamed to INetworkObjectProvider
.
Two new simpler functions to provide instances have been added that can be used for simple use cases like pooling:
C#
public class PooledNetworkObjectProvider : NetworkObjectProviderDefault
{
protected override NetworkObject InstantiatePrefab(NetworkRunner runner, NetworkObject prefab)
{
// Get object from pool and return it.
}
protected override void DestroyPrefabInstance(NetworkRunner runner, NetworkPrefabId prefabId, NetworkObject instance)
{
// Return the instance to the pool.
}
}
The ReleaseInstance
and AcquireInstanceFunctions
have been adjusted.
C#
public void ReleaseInstance(NetworkRunner runner, NetworkObject no, bool isSceneObject)
{
....
}
to
C#
public void ReleaseInstance(NetworkRunner runner, in NetworkObjectReleaseContext context)
{
var no = context.Object;
}
AcquireInstance(NetworkRunner runner, NetworkPrefabInfo info)
is now AqcuirePrefabInstance(NetworkRunner runner, in NetworkPrefabAcquireContext context, out NetworkObject result)
. The return parameter is no longer the object but the result (NetworkObjectAcquireResult.Success)
. The object is passed via the out
parameter instead.
IsSceneObject
in the context parameter has been replaced with context.TypeId.IsSceneObject
.
From:
C#
public NetworkObject AcquireInstance(NetworkRunner runner, NetworkPrefabInfo info)
{
NetworkObject prefab;
if (NetworkProjectConfig.Global.PrefabTable.TryGetPrefab(info.Prefab, out prefab))
{
var newO = ...
return newO;
}
return null;
}
To:
C#
public NetworkObjectAcquireResult AcquirePrefabInstance(NetworkRunner runner, in NetworkPrefabAcquireContext context, out NetworkObject result)
{
NetworkObject prefab;
if (NetworkProjectConfig.Global.PrefabTable.TryGetPrefab(context.PrefabId, out prefab, true) == NetworkPrefabTableGetPrefabResult.Success)
{
var newO = ....
result = newO;
return NetworkObjectAcquireResult.Success;
}
result = null;
return NetworkObjectAcquireResult.Failed;
}
NetworkProjectConfig.Global.PrefabTable.TryGetPrefab(info.Prefab, out prefab)
now has an additional bool
IsSynchronous parameter (set to true to keep same behavior) and returns a NetworkPrefabTableGetPrefabResult
enum instead of a bool.
Change Detection
OnChanged
has been removed. Fusion 2 offers a new more extensive API that allows to detect changes both in Render and FixedUpdateNetwork. You can learn more about the new change detection API here.
Here is a simple example of replacing OnChanged
with the equivalent Render
based change detection.
From:
C#
public class Example : NetworkBehaviour
{
[Networked(OnChanged = nameof(OnStateChanged))]
public int State { get; set; }
public static void OnStateChanged(Changed<Example> changed)
{
var value = changed.Behaviour.State;
changed.LoadOld;
var oldValue = changed.Behaviour.State;
}
}
To:
C#
public class Example : NetworkBehaviour
{
private ChangeDetector _changes;
[Networked]
public int State { get; set; }
public override void Spawned()
{
_changes = GetChangeDetector(ChangeDetector.Source.SimulationState);
}
public override void Render()
{
foreach (var change in _changes.DetectChanges(this, out var previousBuffer, out var currentBuffer))
{
switch (change)
{
case nameof(State):
var reader = GetPropertyReader<int>(nameof(State));
var (previous,current) = reader.Read(previousBuffer, currentBuffer);
OnStateChanged(previous, current);
break;
}
}
}
private void OnStateChanged(int oldValue,int value)
{
}
}
On Changed Render
Instead of using a ChangeDetector, a separate attribute, OnChangedRender
can be used on Networked Properties. This will trigger the assigned method when a change to the Networked Property has been detected.
Here is an example:
C#
public class Example : NetworkBehaviour
{
[Networked, OnChangedRender(nameof(OnColorChanged))]
public Color NetworkedColor { get; set; }
public Material material;
public void OnColorChanged()
{
material.color = NetworkedColor;
}
}
Using the OnChangedRender attribute is a faster alternative to Change Detectors, but it does offer less flexibility and is best reserved for elements that won't affect gameplay too much. Also, it does not support copying the previous state. This can cause issues that, when an object is spawned, changes that should occur when a change is detected such as setting an object's color or display name, can be missed if not checked on Spawned.
Interpolation Target
Interpolation Targets do no longer exist and are not necessary to use with NetworkTransform
. The object with the NetworkTransform
itself will be interpolated accordingly in Render
.
Predicted Spawning
Predicted spawning has been removed and there is no new APi to replaced it. NetworkObjectPredictionKey
is no longer needed, remove it from the Spawn
function.
Physics
NetworkRigidBody
and NetworkPhysicsSimulation
have been removed from the Fusion dll. These have been replaced with the Unity Physics Addon IBeforePhysicsStep
(and after) have been removed and need to be remapped to RunnerPhysicsSimulate.OnBeforeSimulate
(and after)
Shared Mode Improvements
Ticks are now aligned. This means you can use Runner.Tick
to refer to a specific tick in shared mode and share that information with other clients. This also allows for the use of TickTimer
in shared mode.
Simulation Behaviours
SimulationBehaviours
are no longer supported on NetworkObjects
. Replace them with NetworkBehaviour
and remove IOnSpawned/IOnDespawned
interfaces and use override Spawned/Despawned
instead.
FixedUpdateNetwork on Proxies
FixedUpdateNetwork
no longer executes on proxies by default.
It can be manually enabled by calling Runner.SetIsSimulated(Object, true);
. It's best to call this in Spawned
to ensure that FixedUpdateNetwork
starts running immediately.
Scene Management
Scene management has been significantly changed to allow for addressable scenes and additive loading.
Prototyping Add On
As of Fusion 2, the Prototyping add on is no longer supported. If migrating a project that utilized this add on, be sure to move it out of the Fusion folder before deleting it when following the SDK upgrade steps. Many of the scripts in this folder can be updated using the previously listed migration tips, but it is recommended to remove these if they are not being used and/or write simpler versions of them where applicable.
OrderAfter / Before
The OrderAfter
and OrderBefore
attributes have been removed. Instead, Unity's execution order is used. You can find the Script Execution Order
of built-in Fusion types under Edit > Project Settings > Script Execution Order
. Do NOT modify the execution order of built-in Fusion types.
To adjust the execution order of your scripts either manually add them to the list in the project settings or use the [DefaultExecutionOrder(x)] attribute.
E.g. [OrderAfter(typeof(HitboxManager))]
becomes [DefaultExecutionOrder(-1995)]
.
AOI INetworkRunnerCallbacks
There are two new callbacks that are called whenever an object enters or exits the AOI area of the client. Use these callbacks to hide/show objects accordingly.
In Fusion 1 manual detection of entering / exiting AOI was needed instead.
C#
public void OnObjectExitAOI(NetworkRunner runner, NetworkObject obj, PlayerRef player)
{
}
public void OnObjectEnterAOI(NetworkRunner runner, NetworkObject obj, PlayerRef player)
{
}
Back to top