Unity を検索

2022 年の「Boss Room」をのぞいてみよう:Netcode for GameObjects、Relay、そして Lobby

2022年4月14日 カテゴリ: ゲーム | 13 分 で読めます
Boss Room boss
Boss Room boss
シェア

Is this article helpful for you?

Thank you for your feedback!

2021 年 4 月にアーリーアクセス版としてリリースされた「Boss Room」は、Unity ゲーミングサービス(UGS)の多くの要素をフィーチャーし、マルチプレイヤーゲーム開発のハンズオン学習を実現した、Unity の開発者向けの「生きた教育ツール」です。

Boss Room」は、開発者がマルチプレイヤーゲーム開発について学べるように、さまざまな UGS のソリューションを本開発と同等の環境で活用してみせた、マルチプレイヤーゲームのサンプルです。 

Boss Room」には 2 つの大きな目的があります。

  1. このサンプルをコミュニティが自由に利用して、ユーザー自身の Unityゲームの出発点として、あるいはその一部分として使用することのできる教育用サンプルとすること
  2. 自分たちのソリューションのドッグフーディングをすること。サンプルチームは SDK や UGS チームと連携し、このようなジャンルのゲームに共通する機能をすべて備えた、本物のマルチプレイヤーゲームの構築・保守を行っています。新しい利用可能なツールや機能を提供していく中で、「Boss Room」も進化し、機能セットを拡張していきます。

先月、「Boss Room」の v1.1.0-pre がリリースされ、マルチプレイヤーゲーム開発のサービス面を追求する開発者にむけた、まったく新しい機能セットが大々的に公開されました。

ぜひ続きをお読みいただき、「Boss Room」で Unity ゲーミングサービス統合を活用し、プレイヤーがマルチプレイヤー体験に期待するロビー機能を実現した方法に触れてください。 

このブログでは、Lobby、Relay、Authentication サービスのドキュメントページで詳細に説明されていること、たとえば統合までの手順などを繰り返し説明することは避けたいと思います。その代わりに、サービス統合の際に学んだこと、苦労したこと、そしてそれらの課題の解決策に焦点を当てたいと思います。

「Boss Room」のプレイヤー同士をつなぐ

Boss Room Characters in a room

「Boss Room」はマルチプレイヤーゲームなので、ゲームセッションを発見して、参加する方法がなければなりません。

現状、プレイヤーがお互いを見つけ、ゲームに接続するための選択肢が 2 つ用意されています。

ダイレクト IP 接続は、一般に公開されている IP アドレスを使ってユーザー同士が接続する方法です。しかし、他人のコンピューターへの接続は、コンピューターが NAT(ネットワークアドレス変換装置)やルーターで隠蔽されているため、思ったほど簡単にはいかないことが多いようです。 

ポートフォワーディングを使えば接続は可能ですが、他のプレイヤーが接続できるようにするためにホスト側に余分な作業が必要になることに変わりはありません。また、この方法にはゲームセッションを見つけやすくする要素はありません。プレイヤーは、ゲーム外の手段を使って参加情報を共有する必要があります。この接続モードは、インターネット接続を必要とせず、LAN 環境でも動作するのが利点です。 

しかし、「Boss Room」はインターネット経由でもプレイ可能なマルチプレイヤー体験として作られており、セッションを簡単に発見でき、ホストプレイヤーにポートフォワーディングを強制しないことが前提となっています。

ここで Unity ゲーミングサービスが役立ちます。Authentication、Lobby、Relay を組み合わせることで、ポートフォワーディングやゲーム外での調整を必要とせず、インターネット上でプレイ可能なゲームをホストしたり、参加したりすることを容易にすることができます。

Boss Room」に Authentication、Lobby、Relay のサービスを統合してからは、ポートフォワーディングやゲームに参加するための情報を外部と共有する必要がなくなり、よりシンプルにゲームをホストしたり、参加したりすることができるようになったのです。  

全体的に、よりスムーズで迅速な体験ができるようになりました。これは、サンプルでは望ましいくらいのことですが、 製品としてのゲームでは不可欠なことです。

ここでは、私たちが学んだことの一部を皆さんにもご覧いただきます。

「Boss Room」アプリのフロー概要

ゲームプレイの内容で言えば、「Boss Room」は、最大 8 人まで参加可能で、必要な機能をすべて備えた、セッションのホストが存在するタイプの協力マルチプレイヤー RPG です。その機能とゲームプレイについては、こちらのブログ記事で詳しく説明されています。

最初のステップ:Authentication、UGS、ローカルでのイテレーションのワークフロー

Unity ゲーミングサービスの他の機能を利用するためには、ユーザーを認証する必要があります。したがって、ゲームが起動し、メインメニューのシーンがロードされると同時に、Authentication が開始されるようになっています。

Authentication サービスは、匿名でのサインインに対応しており、プレイヤーからの追加入力は必要ありません。

注意点として、Authentication API はデフォルトでは同じマシン上で動作する同じプロジェクトの複数のインスタンスを区別しないため、それらの異なるインスタンスすべてで同じユーザーとしてログインしてしまうということが挙げられます。このため、ローカルでゲームをテストする機能が使えなくます。ParrelSync クローンと実際のゲームビルドの両方がこの影響を受けます。

幸いなことに、簡単な解決策があります。Authentication はプロファイルをサポートしているのです。これが私たちの場合、まさに求めていたものでした。これにより、それぞれのユーザーが実質同じ物理マシン上にいるように扱えたのです。ローカルでテストするには、ビルドとエディターの両方のプレイヤーが異なるプロファイルに切り替えられる必要があります。

ProfileManager クラスは、(存在するならば)使用するプロファイルを決定するロジックをラップしています。ビルドでは、新しいプロファイル ID を指定するために、コマンドライン引数「-AuthProfile」に依存します。エディターでイテレーションを行う場合、ParrelSync に依存するので、このクラスは ParrelSync の「CloneManager」カスタム引数を使用して、使用するユーザープロファイルを決定することも可能です。

「ProfileManager.Profile」を使用して、カスタムの「InitializationOptions」を生成しています。

プロファイルの切り替えやサインインのロジックそのものを実行するコードは以下の通りです。

上記のタスクの完了を待って、他のサービスを利用する準備が整い、ParrelSync とカスタム Profile を利用した場合のローカルでのイテレーションのワークフローがある程度自動化されました。最近「Boss Room」は、ツールに縛られないように上記の処理を dataPath ベースに変更しましたが、上に示した解決策は ParrelSync を使う場合はいぜん有効です。

ロビー作成:ホストのフロー

  • ホストとなる人は、ロビー名を入力し、公開か非公開かを指定して「作成」ボタンを押す
  • ロビー作成 API が呼び出される新しく作成されたロビーは、以下のリレー割り当てとネットコード起動の手順が正常に完了するまで、「ロック」されます(つまり、設定が完了して、参加可能な公開ゲームのリストに表示されないようになります)。
  • ホストは Relay サービスにリレー割り当てを要求する
  • UTP が開始され、ホストがキャラクター選択シーンに切り替わります。ロビーそのものはロックが解除されたと判定され、他のクライアントが参加できるようになる
Lobby menu in Boss Room

ロビーへの参加:クライアントのフロー

  • ロビーへの接続方法はいくつかあります。
    • ロビーサービスから定期的に取得される公開ロビーの中から 1 つ選択する
    • 公開ロビーをランダムに選択する Quick Join を使う
    • ゲーム外の手段で共有されたロビーキーを使用する。これは、公開ロビー、非公開ロビーのどちらにも使える
  • ロビーに参加した後は、ロビーのメタデータで渡されたリレージョインコードを使って、UTP Relayトランスポートでホストに接続することになります。
  • ホストは、接続するクライアントを承認するリクエストを受け取り、すべてがうまくいけば、ホストはサーバー権威で適切なシーンに切り替え、プレイヤーに提示します。

プレイヤーがホストまたはゲームに接続したとき

接続すると、プレイヤーはキャラクター選択シーンに入り、用意された 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 分)、この仕組みにのみ依存することはできません。

ロビーからの退出処理をより堅牢なものにするために、クリーンアップを行う仕組みがいくつか追加されています。

  • クライアントコードにはアプリケーション終了ロジック(ApplicationController.cs の OnWantToQuit and LeaveSession を参照)が含まれており、ロビーからプレーヤーを削除するリクエストを送信します。
  • ホストは、ホストがあるプレイヤーが切断されたことを知るとすぐにその切断されたプレイヤーをロビーから排除する特別なロジックを持っています(NetworkManager.OnClientDisconnectCallback を利用しています)。これは、クライアントがクラッシュして「ロビーを退出する」リクエストを送信できなかった場合に役に立ちます。これを動作させるために、ホストは SessionManager を使って、UGS playerId とクライアントの NGO clientId の間のマッピングを保存します。このロジックは、ServerGameNetPortal.cs の OnClientDisconnect に記述されています。

最後に、クライアントにはホストがロビーを離れたかどうかを判断するチェック処理を持っています。そしてホストがロビーを離れたことを検知した場合は、クライアントもロビーを離れます。この処理を行うコードは、ClientGameNetPortal.cs の OnDisconnectOrTimeout に記述されています。

今後の予定

UGS のポートフォリオとネットワークソリューションが成長し、改良され続けるのと同じく、「Boss Room」のサンプルも発展し続けるでしょう。今後、プロジェクトに関わりたい方向けには、以下のような方法をご提案します。

ネットワークを使ったプロジェクトを自分で始められた方は、Discord または Unity Multiplayer フォーラムでチャットして、経験を共有したり、助けを求めたりしましょう。

2022年4月14日 カテゴリ: ゲーム | 13 分 で読めます

Is this article helpful for you?

Thank you for your feedback!

フォーラムでディスカッションに参加する