Custom Realtime Client
Overview
Starting with Fusion 2.1, it is possible to use a custom Realtime Client with Fusion, enabling advanced use cases not yet covered by the Fusion API. This allows:
- Complete control over the matchmaking process even before starting Fusion.
- Make use of new features directly from the Realtime SDK that are not exposed yet via Fusion APIs.
This allows Fusion clients to use entirely custom matchmaking processes that are not yet supported by Fusion API, like the usage of SQL Lobbies or the new Ticket System. Along with that, Fusion 2.1 comes with the new Realtime v5 SDK, which includes a lot of extra features.
Custom Realtime Client
In order to connect to the Photon Cloud, the Fusion SDK always makes use of a Realtime Client instance, which is used to connect the peer to a Photon Region and eventually to a Game Session.
With Fusion 2.1, it is now possible to pass along with the other StartGameArgs a custom instance of a RealtimeClient, which will be used by the peer to connect to the Photon Cloud.
C#
var startResult = await networkRunner.StartGame(new StartGameArgs {
// Other arguments
RealtimeClient = [RealtimeClient]
});
This parameter is completely optional, and by default, if that argument is not passed, Fusion will create and manage the lifecycle of an internal Realtime client instance.
If an instance is passed when starting a NetworkRunner, Fusion will:
- Check if it has not yet connected to the Photon Cloud, and connect if necessary.
- Check if it has not yet joined a Session, and join if necessary.
- Start the Fusion simulation as usual.
This means that a custom Realtime client instance can be used for any prior task (especially matchmaking), before starting any Fusion-related code.
Basic Example
Here, a simple matchmaking script using a custom Realtime Client will be described, which will handle:
- Connecting to the Photon Cloud;
- Creating/Joining a Session by ID and at random;
- Join a Lobby and join an already created Session.
C#
using System.Threading.Tasks;
using Fusion;
using Fusion.Matchmaking;
using Fusion.Photon.Realtime;
using Photon.Realtime;
using UnityEngine;
public class SimpleMatchmaker : MonoBehaviour
{
// NetworkRunner Prefab Reference
public NetworkRunner runnerPrefab;
// Internal references
private RealtimeClient _client;
private NetworkRunner _runner;
// Setup Realtime Client if necessary
private void SetupRealtimeClient()
{
if (_client != null) return;
// Create a Realtime Client and set it up for Fusion usage
_client = new RealtimeClient().SetupForFusion(); // must be invoked, see below
_client.AddCallbackTarget(this);
}
private void Start()
{
// Keep it around
DontDestroyOnLoad(this.gameObject);
}
private void Update()
{
// Check if NetworkRunner is valid
if (_runner == false)
{
// Run updates
_client?.Service();
}
}
// Join a Lobby to look for a Session to Join
private async Task JoinSessionLobby()
{
Debug.Log("Join Session Lobby...");
SetupRealtimeClient();
// Connect to the Photon Cloud
await _client.ConnectUsingSettingsAsync(PhotonAppSettings.Global.AppSettings);
// Join Lobby
await _client.JoinLobbyAsync();
if (_client.InLobby)
{
Debug.Log($"Joined Lobby: {_client.CurrentLobby.Name} [{_client.CurrentLobby.Type}]");
}
}
// Connect to a given Room Name or join a random one
// if no roomName is passed
private async Task ConnectToRoom(string roomName = null)
{
Debug.Log($"ConnectToRoom: {roomName}");
SetupRealtimeClient();
// Setup Matchmaking
var matchmakingArguments = new MatchmakingArguments
{
RoomName = roomName // if null, a random name will be generated by the Photon Cloud
}.SetupForFusion(); // must be invoked, see below
await _client.ConnectToRoomAsync(matchmakingArguments);
if (_client.InRoom)
{
Debug.Log($"Client is in room: {_client.CurrentRoom.Name} [{_client.CurrentRegion}]");
}
else
{
Debug.LogError($"Unable to join Room");
}
}
// Disconnect the client from the Photon Cloud
private async Task DisconnectFromCloud()
{
Debug.Log("Disconnecting...");
if (_client != null)
{
await _client.DisconnectAsync();
}
_client = null;
}
}
Important points to observe:
- When creating a new
RealtimeClientinstance that is going to be used with Fusion, it is required to call theSetupForFusion()utility method. This will set up some of the client parameters to work with the Fusion SDK properly. - When creating an instance of
MatchmakingArgumentsto be used with the Realtime Async API, it is required to call theSetupForFusion()utility method. This will copy some of the settings from Fusion into Realtime'sMatchmakingArguments, which must be set before connecting to the Photon Cloud.
The script above just wraps some utility methods around a RealtimeClient instance.
To know more about how to handle the RealtimeClient instance, please follow the Realtime SDK documentation page here.
It can be extended with the following:
C#
private async Task StartGame(GameMode gameMode)
{
Debug.Log("Starting game...");
_runner = Instantiate(runnerPrefab);
var sceneInfo = new NetworkSceneInfo();
var sceneRef = SceneRef.FromIndex(0);
if (sceneRef.IsValid)
{
sceneInfo.AddSceneRef(sceneRef, LoadSceneMode.Additive);
}
var result = await _runner.StartGame(new StartGameArgs()
{
GameMode = gameMode,
RealtimeClient = _client, // passing the custom Realtime Client
Scene = sceneInfo
});
if (result.Ok)
{
Debug.Log($"Runner has started: {_runner.SessionInfo.Name}");
}
}
This method just illustrates how to start a new NetworkRunner and pass the custom RealtimeClient instance via the StartGameArgs.RealtimeClient. By default, this variable is set to null, meaning that Fusion will handle its creation and management, but if an instance is passed, that one will be used internally.
One important detail to note is that, while the RealtimeClient is being used "outside" Fusion, it requires the RealtimeClient.Service() to be invoked regularly for all communication to be processed (observe the Update() method above). That is just how the Realtime SDK works, because up to this point, there is no interference of Fusion in its usage.
When that instance is passed via the StartGameArgs, the regular update requirement will be taken care of automatically by the Fusion SDK, as usual, and there is no need to call it again.
There is a dedicated page for the Realtime Async API.
Back to top