This document is about: FUSION 2
SWITCH TO

カスタムRealtimeClient

概要

Fusion 2.1以降でカスタムRealtimeClientが使用できるようになり、Fusion APIがまだサポートしていない高度なユースケースに対応可能になります。

  1. Fusionを開始する前段階で、マッチメイキングプロセスを完全に制御可能
  2. Fusion APIが未対応の新機能をRealtime SDKから直接利用可能

これによって、SQLロビーや新しいチケットシステムなど、Fusion APIでは未対応のマッチメイキングプロセスを完全に実現できます。さらにFusion 2.1では、新しいRealtime SDK v5が提供されていて、多くの新機能が搭載されています。

カスタムRealtimeClient

Fusion SDKは、必ずRealtimeClientを利用してPhoton Cloudに接続します。これは、ピアをPhotonリージョンに接続し、最終的にゲームセッションへ接続するために使用されます。

Fusion 2.1では、StartGameArgsにカスタムRealtimeClientインスタンスを渡して、Photon Cloudへ接続するために使用できます。

C#

var startResult = await networkRunner.StartGame(new StartGameArgs {
  // その他の引数
  RealtimeClient = [RealtimeClient]
});

このパラメーターは完全なオプションで、デフォルトで引数が渡されない場合、Fusion内部でRealtimeClientインスタンスが作成されて、そのライフサイクルが管理されます。

NetworkRunner開始時にインスタンスが渡されると、Fusionで以下のプロセスが実行されます。

  1. Photon Cloudにまだ接続していないかを確認し、必要なら接続します。
  2. セッションへ参加していないかを確認し、必要なら参加します。
  3. 通常通りにFusionシミュレーションを開始します。

これによって、Fusion関連のコードを開始する前に、任意の事前処理(特にマッチメイキングなど)をカスタムRealtimeClientで使用できます。

基本的な例

ここでは、カスタムRealtimeClientを使用した単純なマッチメイキングのスクリプトについて解説します。

  1. Photon Cloudへの接続
  2. ID指定またはランダムなセッションの作成/参加
  3. ロビーへの参加と既存セッションへの参加

C#

using System.Threading.Tasks;
using Fusion;
using Fusion.Matchmaking;
using Fusion.Photon.Realtime;
using Photon.Realtime;
using UnityEngine;

public class SimpleMatchmaker : MonoBehaviour
{

    // NetworkRunnerプレハブの参照
    public NetworkRunner runnerPrefab;

    // 内部の参照
    private RealtimeClient _client;
    private NetworkRunner _runner;

    // 必要に応じたRealtimeClientのセットアップ
    private void SetupRealtimeClient()
    {
        if (_client != null) return;

        // RealtimeClientの作成と、Fusion用のセットアップ
        _client = new RealtimeClient().SetupForFusion(); // 呼び出し必須(後述)
        _client.AddCallbackTarget(this);
    }

    private void Start()
    {
        // インスタンスを維持する
        DontDestroyOnLoad(this.gameObject);
    }

    private void Update()
    {
        // NetworkRunnerが有効かどうかを確認
        if (_runner == false)
        {
            // 更新を実行
            _client?.Service();
        }
    }

    // セッションを探すためにロビーへ参加する
    private async Task JoinSessionLobby()
    {
        Debug.Log("Join Session Lobby...");

        SetupRealtimeClient();

        // Photon Cloudへ接続する
        await _client.ConnectUsingSettingsAsync(PhotonAppSettings.Global.AppSettings);

        // ロビーへ参加する
        await _client.JoinLobbyAsync();

        if (_client.InLobby)
        {
            Debug.Log($"Joined Lobby: {_client.CurrentLobby.Name} [{_client.CurrentLobby.Type}]");
        }
    }

    // ルーム名を指定して接続するか、
    // 指定されなければランダムなルームへ接続する
    private async Task ConnectToRoom(string roomName = null)
    {
        Debug.Log($"ConnectToRoom: {roomName}");

        SetupRealtimeClient();

        // マッチメイキングのセットアップ
        var matchmakingArguments = new MatchmakingArguments
        {
            RoomName = roomName // nullなら、ランダムな名前がPhoton Cloudによって生成される
        }.SetupForFusion(); // 呼び出し必須(後述)

        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");
        }
    }

    // Photon Cloudからクライアントを切断する
    private async Task DisconnectFromCloud()
    {
        Debug.Log("Disconnecting...");

        if (_client != null)
        {
            await _client.DisconnectAsync();
        }

        _client = null;
    }
}

気を付けるべき重要なポイント:

  1. Fusionで使用する新しいRealtimeClientインスタンスを作成する際は、SetupForFusion()メソッドを呼び出す必要があります。これによって、Fusion SDKで適切に動作するためのクライアントのパラメーターが設定されます。
  2. Realtime Async APIで使用するMatchmakingArgumentsインスタンスを作成する際は、SetupForFusion()メソッドを呼び出す必要があります。これによって、RealtimeのMatchmakingArgumentsにFusionの設定の一部がコピーされます。これは、Photon Cloud接続前に必ず設定する必要があります。

上記スクリプトは、RealtimeClientインスタンスをラップする汎用メソッド群です。
RealtimeClientインスタンスの処理方法の詳細については、Realtime SDKのドキュメントページをご覧ください。

カスタムRealtimeClientは以下のように使用できます。

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, // カスタムRealtimeClientを渡す
        Scene = sceneInfo
    });

    if (result.Ok)
    {
        Debug.Log($"Runner has started: {_runner.SessionInfo.Name}");
    }
}

この例は、新しいNetworkRunnerを開始し、カスタムRealtimeClientインスタンスをStartGameArgs.RealtimeClient経由で渡す方法を示しています。デフォルトではこの変数はnullに設定されていて、Fusionが作成と管理を処理しています。ここにインスタンスが渡されると、そのインスタンスが内部で使用されるようになります。

重要な注意点としてRealtimeClientをFusion"外部"で使用する場合、定期的にRealtimeClient.Service()を呼び出して(前述のUpdate()メソッドを参照)、すべての通信を処理する必要があります。これはRealtime SDKの基本的な仕組みで、その時点ではFusionがRealtimeの使用に干渉していないためです。
このインスタンスをStartGameArgs経由で渡した場合、Fusion SDKによって定期的な更新が自動的に処理されるため、メソッドを再度呼び出す必要はありません。

Realtime Async APIの詳細ページもご覧ください。

Back to top