はじめに
オンラインゲームの開発では、クライアントやサーバーがどのようなネットワークを構成するか、ということを決めて実装する必要があります。これを「ネットワークトポロジー」といいます。サーバーが介在するもの、プレイヤー同士だけで完結するものもあります。
ネットワークトポロジー毎に向いているゲームタイプや、掛かるコスト、実装方法など様々な差異があるため、オンラインマルチプレイゲームの設計をするにあたってその選定は非常に重要です。
これに関して「ソーシャルハブ」という公式サンプルが公開されています。これは同一プロジェクト内でネットワークトポロジーを複数使い分けるというものです。
そこで本記事ではネットワークトポロジー毎の基本的な特徴を紹介しつつ、公式サンプルを用いて複数のトポロジーを併用する方法について紹介します。
前提記事
Photon Fusionの基本的な解説は以下の記事で行っていますので、そちらを参照下さい。
Photon Fusion for Unityの導入手順とPUN2との機能比較
動作確認環境
Windows 11 Home 22H2
Unity 2020.3.441f1
Fusion SDK 1.1.6 F Build 696
Photon Fusionで扱えるネットワークトポロジー
Photon Fusionでは、以下4種類のネットワークトポロジーから設定できます。
サーバーモード
オンラインゲームでよくある形態で、サーバー上で専用プログラムが常時動いており、クライアント(=プレイヤー)がそこへ接続する形です。
サーバーがシミュレーションの権限を持つためチートに強く、接続の安定性も高いですがサーバーの運用コストが掛かるのが最大のネックとなります。
ホストモード
プレイヤーの一人がサーバーも担うような接続方法です。
サーバーコストも掛からずPhoton Fusionの様々な機能も使えますが、ホストがシミュレーションの権限を持つためチート行為に弱くなってしまいます。
また、ホストが抜けたときにゲームを継続する仕組みであるホストマイグレーションが必要になると、実装の難易度がやや上がります。
共有モード
接続する全てのプレイヤーが同程度の権限を持って接続をする方法です。
オブジェクト操作の権限が分散しているため、最後の一人が抜けるまでルームの維持が可能です。
ラグ補償ヒットボックスなどいくつかの機能が使えませんが、学習コストや実装難易度が比較的低くなっています。
なお、Photon Fusionの前身であるPUN2とほぼ同様の動作となっています。
シングルモード
一切通信を行わないオフラインモードです。
通信するかどうか以外の実装や動作などについては、ホストモードのホストと同じになります。つまりホストモードとして実装をした後、後述する方法で設定を変更すればそのまま問題なく動作します。
ネットワークトポロジーの選択方法
ネットワークトポロジーを選択するには、Photon Cloudへ接続する際のオプションとしてコード内で指定する必要があります。
まず初期化処理オプションを設定するためのStartGameArgsのインスタンスを作成します。その中のGameModeメンバ変数でネットワークトポロジーを設定します。
その後Photon Cloudとの接続用メソッドであるStartGameを実行すれば、設定したネットワークトポロジーでの接続が実行されます。
await _runner.StartGame(new StartGameArgs()
{
GameMode = mode,
SessionName = "TestRoom",
Scene = SceneManager.GetActiveScene().buildIndex,
SceneManager = gameObject.AddComponent<NetworkSceneManagerDefault>()
});
ネットワークトポロジーはこの変数だけで設定できるため簡単に変更が可能ですが、それぞれ実装の指針に大きな差異があります。そのため開発の初期段階で決めておかないと、大きな手戻りが発生する可能性があることに注意が必要です。
その差異については「Photon Fusion for UnityのWebGLビルドを1週間ゲームジャムで試して得た知見」の記事で少し解説していますが、詳しくは今後の記事で解説する予定です。
ネットワークトポロジーの選定基準
サーバー | ホスト | 共有 | |
---|---|---|---|
コスト | ☓ | ○ | ○ |
ルーム人数 | ○ | △ | △ |
ルームの維持 | ○ | △ | ○ |
チート耐性 | ○ | △ | △ |
Fusionの機能 | ○ | ○ | △ |
通信安定性 | ○ | △ | ○ |
-
コスト
サーバーの運用コスト(支払い)が掛けられるかが焦点になります。 -
ルーム人数
同じルームで同時に遊ぶ人数です。ホストモードや共有モードでMMOやバトルロイヤルなどの多人数参加型のゲームを作るのは現実的ではありません。 -
ルームの維持
主に少人数のマッチにおけるルーム維持のしやすさです。 -
チート耐性
サーバーモードなら安心というわけではないですが、プレイヤーに権限がないため堅牢です。
Photon Fusionとは関係ない部分として、課金や育成、対戦、ランキングなどの要素がある場合はチートを行う動機も強くなります。 -
Photon Fusion特有の機能を使う必要があるか
ラグ補償(Lag Compensation)や、クライアントサイド予測(Client-Side Prediction)とサーバーリコンシリエーション(Server Reconciliation)によるロールバック・再シミュレーションが必要かどうかです。共有モードでは使えないという場合がほとんどです。 -
通信安定性
ホストモードではプレイヤーの環境に大きく依存します。
ネットワークトポロジーを複数利用する
前述の通り、ネットワークトポロジーの切り替えは接続パラメータを変更するだけでできます。そのため、1つのゲーム内において複数のネットワークトポロジーを採用することも容易にできます。
ただし接続後の実装については差があるため、ロビー機能だけ共有モードを使うなど、ゲームモード毎に最適なものを選択する方がよいでしょう。同一ゲームモードを複数のトポロジーに対応させるのは実装難易度が上がってしまいます。
公式サンプルについて
ソーシャルハブはネットワークトポロジーを複数利用するための実装サンプルになっています。
- 操作
左クリック 攻撃(木箱を破壊する、ダンジョン内のみ)
Eキー インタラクト(NPCに話しかける)
WASDキー 移動
サンプルは、ロビーに集まり数人のPTでインスタンスダンジョンに行くMOのような作りになっています。
ゲームを起動すると、プレイヤーはまずロビーに接続します。他のプレイヤーをロビー上部の出口で待ち受け、任意のタイミングでダンジョンへ出発します。
公式サンプルのネットワークトポロジーについて
ロビーはプレイヤーの出入りが多く、メインのゲーム部分に比べ高度な同期が不要なことから、ネットワークトポロジーは共有モードが採用されています。
ダンジョンはプレイヤーが出発時点でほぼ固定され、アクションや射撃などの高度な同期が必要になります。そのためネットワークトポロジーにはクライアントホストが採用されています。
なお、サンプルはシングルピアモード前提で実装されており、マルチピアモードに対応させるには工夫が必要です。
ネットワークトポロジーを切り替える処理のポイント
サンプルでは主にConnectionManager.csで切り替えを実行しています。
-
ConnectToRunnerメソッド
新しいRunnerを生成 connection.Runner = child.AddComponent();
StartGameで接続処理 var startResult = await connection.Runner.StartGame -
LoadDungeonLevel
shutdownで使わない方のRunnnerをDispose(破棄)
SetActiveSceneで次のシーンへ切り替え
ポイントはNetworkRunnerを複数同時に生成し接続処理をすることができるところです。これにより現在の接続を維持したまま次の接続の準備ができます。
ただし単一プレイヤーだとしても、複数の接続を行うとその分CCUとして計上されてしまいます。Photon Fusionの利用料金にも掛かってくるため、Dispose処理を忘れないように注意する必要があります。