2021 年 4 月にアーリーアクセス版としてリリースされた「Boss Room」は、Unity ゲーミングサービス(UGS)の多くの要素をフィーチャーし、マルチプレイヤーゲーム開発のハンズオン学習を実現した、Unity の開発者向けの「生きた教育ツール」です。
「Boss Room」は、開発者がマルチプレイヤーゲーム開発について学べるように、さまざまな UGS のソリューションを本開発と同等の環境で活用してみせた、マルチプレイヤーゲームのサンプルです。
「Boss Room」には 2 つの大きな目的があります。
先月、「Boss Room」の v1.1.0-pre がリリースされ、マルチプレイヤーゲーム開発のサービス面を追求する開発者にむけた、まったく新しい機能セットが大々的に公開されました。
ぜひ続きをお読みいただき、「Boss Room」で Unity ゲーミングサービス統合を活用し、プレイヤーがマルチプレイヤー体験に期待するロビー機能を実現した方法に触れてください。
このブログでは、Lobby、Relay、Authentication サービスのドキュメントページで詳細に説明されていること、たとえば統合までの手順などを繰り返し説明することは避けたいと思います。その代わりに、サービス統合の際に学んだこと、苦労したこと、そしてそれらの課題の解決策に焦点を当てたいと思います。
「Boss Room」はマルチプレイヤーゲームなので、ゲームセッションを発見して、参加する方法がなければなりません。
現状、プレイヤーがお互いを見つけ、ゲームに接続するための選択肢が 2 つ用意されています。
ダイレクト IP 接続は、一般に公開されている IP アドレスを使ってユーザー同士が接続する方法です。しかし、他人のコンピューターへの接続は、コンピューターが NAT(ネットワークアドレス変換装置)やルーターで隠蔽されているため、思ったほど簡単にはいかないことが多いようです。
ポートフォワーディングを使えば接続は可能ですが、他のプレイヤーが接続できるようにするためにホスト側に余分な作業が必要になることに変わりはありません。また、この方法にはゲームセッションを見つけやすくする要素はありません。プレイヤーは、ゲーム外の手段を使って参加情報を共有する必要があります。この接続モードは、インターネット接続を必要とせず、LAN 環境でも動作するのが利点です。
しかし、「Boss Room」はインターネット経由でもプレイ可能なマルチプレイヤー体験として作られており、セッションを簡単に発見でき、ホストプレイヤーにポートフォワーディングを強制しないことが前提となっています。
ここで Unity ゲーミングサービスが役立ちます。Authentication、Lobby、Relay を組み合わせることで、ポートフォワーディングやゲーム外での調整を必要とせず、インターネット上でプレイ可能なゲームをホストしたり、参加したりすることを容易にすることができます。
「Boss Room」に Authentication、Lobby、Relay のサービスを統合してからは、ポートフォワーディングやゲームに参加するための情報を外部と共有する必要がなくなり、よりシンプルにゲームをホストしたり、参加したりすることができるようになったのです。
全体的に、よりスムーズで迅速な体験ができるようになりました。これは、サンプルでは望ましいくらいのことですが、 製品としてのゲームでは不可欠なことです。
ここでは、私たちが学んだことの一部を皆さんにもご覧いただきます。
ゲームプレイの内容で言えば、「Boss Room」は、最大 8 人まで参加可能で、必要な機能をすべて備えた、セッションのホストが存在するタイプの協力マルチプレイヤー RPG です。その機能とゲームプレイについては、こちらのブログ記事で詳しく説明されています。
Unity ゲーミングサービスの他の機能を利用するためには、ユーザーを認証する必要があります。したがって、ゲームが起動し、メインメニューのシーンがロードされると同時に、Authentication が開始されるようになっています。
Authentication サービスは、匿名でのサインインに対応しており、プレイヤーからの追加入力は必要ありません。
注意点として、Authentication API はデフォルトでは同じマシン上で動作する同じプロジェクトの複数のインスタンスを区別しないため、それらの異なるインスタンスすべてで同じユーザーとしてログインしてしまうということが挙げられます。このため、ローカルでゲームをテストする機能が使えなくます。ParrelSync クローンと実際のゲームビルドの両方がこの影響を受けます。
幸いなことに、簡単な解決策があります。Authentication はプロファイルをサポートしているのです。これが私たちの場合、まさに求めていたものでした。これにより、それぞれのユーザーが実質同じ物理マシン上にいるように扱えたのです。ローカルでテストするには、ビルドとエディターの両方のプレイヤーが異なるプロファイルに切り替えられる必要があります。
ProfileManager クラスは、(存在するならば)使用するプロファイルを決定するロジックをラップしています。ビルドでは、新しいプロファイル ID を指定するために、コマンドライン引数「-AuthProfile」に依存します。エディターでイテレーションを行う場合、ParrelSync に依存するので、このクラスは ParrelSync の「CloneManager」カスタム引数を使用して、使用するユーザープロファイルを決定することも可能です。
「ProfileManager.Profile」を使用して、カスタムの「InitializationOptions」を生成しています。
プロファイルの切り替えやサインインのロジックそのものを実行するコードは以下の通りです。
上記のタスクの完了を待って、他のサービスを利用する準備が整い、ParrelSync とカスタム Profile を利用した場合のローカルでのイテレーションのワークフローがある程度自動化されました。最近「Boss Room」は、ツールに縛られないように上記の処理を dataPath ベースに変更しましたが、上に示した解決策は ParrelSync を使う場合はいぜん有効です。
接続すると、プレイヤーはキャラクター選択シーンに入り、用意された 8 人のヒーローの中から 1 人を選びます。すべてのプレイヤーの準備が整うと、短いタイマーが表示され、すべてのヒーローは実際のゲームプレイが行われる Boss Room 環境に移動します。
UGS の Lobby とゲーム内の「ロビー」、つまりキャラクター選択シーンとは区別する必要があります。「Boss Room」のキャラクター選択シーンは、ネットコードで動いています。
ここで重要なのは、Lobby サービスに任意のメタデータを渡すことが可能であるため、その機能を利用して同様のキャラクター選択シーンを実装できる点です。
現在は、Lobby サービスの更新をポーリングする必要があり、キャラクター選択の応答性を高めるには不向きですが、将来的に Lobby サービスからリアルタイムに更新を取得するオプションが提供されれば、このような実装の代替手段としても良いと思われます。
マルチプレイヤーゲームでは、プレイヤーの切断と再接続を処理することが必要です。
「Boss Room」では、セッション管理システムを使用しており、プレイヤーが切断したときに、一部のデータを保存し、再接続したときにそのプレイヤーに正確に割り当てられるようになっています(SessionManager.cs の OnClientDisconnect を参照)。
再接続時にユーザーデータを復元する方法は、SessionManager.cs の SetupConnectingPlayerSessionData に記述されており、ホストによって処理される接続承認チェックの一部として呼び出されます(ServerGameNetPortal.cs の ApprovalCheck を参照)。
ゲーム内にロビーができたことで、切断されたプレイヤーを速やかにロビーから排除することが重要です。そうしないと、切断されたプレイヤーはまだロビーにいるとみなされるため、ロビーに再参加することができません。
プレイヤーが Relay から切断した場合、最終的には Lobby と Relay サービスの統合(UTP 接続を実行する前に有効にする必要があります)が切断したプレイヤーをキックしますが、切断のタイムアウトはかなり長く(最長で 2 分)、この仕組みにのみ依存することはできません。
ロビーからの退出処理をより堅牢なものにするために、クリーンアップを行う仕組みがいくつか追加されています。
最後に、クライアントにはホストがロビーを離れたかどうかを判断するチェック処理を持っています。そしてホストがロビーを離れたことを検知した場合は、クライアントもロビーを離れます。この処理を行うコードは、ClientGameNetPortal.cs の OnDisconnectOrTimeout に記述されています。
UGS のポートフォリオとネットワークソリューションが成長し、改良され続けるのと同じく、「Boss Room」のサンプルも発展し続けるでしょう。今後、プロジェクトに関わりたい方向けには、以下のような方法をご提案します。
ネットワークを使ったプロジェクトを自分で始められた方は、Discord または Unity Multiplayer フォーラムでチャットして、経験を共有したり、助けを求めたりしましょう。