Unity ネットワーク技術メモ
最終更新日:2023年10月31日記事作成日:2021年08月09日
UnityでオンラインゲームやマルチプレイヤーのVR体験、メタバースプラットフォーム等を開発する場合に検討対象となる技術のメモです。
更新履歴
(2023年10月31日)Photonのメッセージ数制限が撤廃されたのを反映
(2023年7月30日)Multiplayer Play Modeの説明を補足
(2023年4月13日)Multiplayer Play Modeについて追記
(2022年11月5日)「Unityでのマルチプレイヤー開発の効率化」にMultiplayer Play Modeについて追記
(2022年8月27日)Oculusプラットフォームの一部機能が非推奨になるのを反映
ネットワーク構成について
Dedicated Server(専用サーバー)
サーバーにすべてのプレイヤーがクライアントとして接続する方式。クライアント間の通信はすべてサーバー経由で行われる。サーバーはローカルネットワーク内に立てたり、クラウドに立てて適宜スケールさせる(ゲームサーバーホスティングを参照)。
クライアントが誰も接続していないときもサーバーが動いている限り状態が維持されている。サーバー費用と運用のコストがかかる。
サーバーにUnityを使用する場合
Unityでビルドした実行ファイルをゲームサーバーとして用いる方式。クライアントと同じプロジェクトファイルをサーバープログラムとしてビルドする。サーバー側でクライアント側と同じ情報を用いてゲームのロジックを実行できる特徴がある。ゲームエンジン製のサーバーは負荷が重い傾向。
サーバーにUnityを使用しない場合
単体のプログラムとしてゲームサーバーを書く方式。リアルタイムオンラインゲームではC++、Java、Go、C#等の高速な言語を用いることが多い。gRPCやMagicOnion等を使用することがある。
Listen Server
プレイヤーの1人がサーバーの役割を兼ね(ホスト)、他のプレイヤーのクライアントが接続する方式。ゲームを一般公開するためには、クライアント同士がお互いの存在を知って通信を開始できるようにするためのマッチングサーバーが必要(いわば「引き合わせはしたからあとはみんなでやり取りしてね」という方式)。P2Pで直接通信することが多い(多かった)が、NAT等で疎通できない場合が多いので、通信を経由するリレーサーバーが必要。マッチングサーバーやリレーサーバーをSaaSとして提供しているPhoton Cloudのようなサービスがある。
一般にホストとなるプレイヤーはゲームシミュレーションを行うので他のクライアントに比べて負荷がかかる。ホストが終了するとクライアントが切断されてしまうので、必要な場合は、別のクライアントをホストにして再接続する(ホストマイグレーション)。
PhotonではP2P通信はせずメッセージ通信は必ずリレーサーバー経由になる。また、「マスタークライアント」という概念があり、ホストマイグレーションが簡単に行える。
マルチプレイヤーの実現方法
ネットワークAPIを使用する
クライアントもサーバーもUnityにする方式です。特にNetcode for GameObjectsはUnityのいわゆる公式ソリューションになります。
Netcode for GameObjects
Unity公式のネットワークAPI。以前はMLAPIという名前だった。名前が長いのはDOTS NetCodeがあるため。
Dedicated Server方式とListen Server方式どちらも可能。今後のロードマップが示されており、長期的に使えることが期待できる。ホストマイグレーションはサポートしていない。手動でホストマイグレーションするヒント。
- Boss Room:公式のサンプル。アーキテクチャの解説が分かりやすい
- Bitesize Samples:もっとシンプルなサンプル2つ
マッチングサーバーはUnity Lobby、リレーサーバーはUnity Relayや非公式のMLAPI.Relayが使用できる(.NET Core製)。
また、Photon Realtimeのカスタムトランスポートがあり、Photonのリレーサーバーが利用可能。Boss RoomサンプルがUnity Relayへの繋ぎで使用していた。エディタで接続するとすぐ切断される不具合がある模様(ビルドすると大丈夫)。Photonのホストマイグレーションは利用できないので注意。
Mirror
UNetという昔のUnityのネットワークAPIがあったが、それを正常進化させたような存在。専用サーバー方式とListen Server方式どちらも可能。
リレーサーバーや専用サーバーを自分で立てる必要がある。実績が豊富。専用サーバーで150ユーザーとか行けるらしい。
WebGLビルドでサーバーをホストできるらしいリレーサーバー。
ネットワークサービスを利用する
自分でサーバーを立てなくてもオンラインゲームを開発できるネットワークサービスが各社より提供されています。
Photon
ドイツExit Games社が運営するゲームネットワークサービスとそのSDK。UnityのSDKであるPUN(Photon Unity Networking)がある。
クラウドサービスのPhoton Cloudが基本。料金体系は主に同時接続者数(CCU)で課金され、20ユーザーを超えると有料になる。ルームを立ててその中にユーザーが入る方式。デフォルトの動作としてはルームが一杯になると新しいルームが自動的に作られる。
サーバーを自分で立てるPhoton Serverもある。サーバー費用・運用のコストがかかる。こちらもCCUで課金される。
多くのオンラインゲームで使用されていて実績がある。ソーシャルVRではVRChatやRec Roomが使用している。また、WebGLビルドでもそこそこいい感じに動く(ただしトランスポートにWebSocketが使用されTCP通信になる)。
o8queさんのドキュメントが神。
Photon Serverを使えばローカルネットワーク内でも使用できる。が、ライセンス認証のためにインターネット接続が必要。インターネットに接続できない場合はオフラインライセンスを提供しているとのこと(ページ右下の記述、フォーラムの回答)。
なお、Exit Games社の経営基盤については、2007年に460万ドル、2021年8月に5000万ドルの投資を受けた記事が見つかる。
Photon Fusion
Photon PUNとBoltを統合した次世代サービス。お値段がやや高めになっている。
大きくSharedモードとHostedモードがある。SharedモードはPUNとほぼ同じ方式。
HostedモードはListen ServerまたはDedicated Serverのトポロジで、サーバー(ホスト)がすべてのネットワークオブジェクトのオーソリティを持つ。それに伴いラグ補償や位置予測、ロールバックが使用できる。Netcode for GameObjectsやMirrorと比べ帯域使用が6分の1で、60Hzで最大200プレイヤーを実現するとのこと(公称)。ホストマイグレーションのAPIがある。
Normcore
ニューヨークのスタートアップ企業・Normal社が2019年5月にリリースした新興のUnity用ゲームネットワークサービス。ボイスチャットもあり。Half + Halfという同社のVRゲームで使用されている。
クラウドサーバーがあり、$49/月でCCU等の制限がなくなる(代わりに帯域制限がある)。ゲーム以外でも使用可能(トップページにenterprise collaboration toolsの記述がある)。パブリッククラウドでは対応できない場合にエンタープライズ向け・オンプレミスも可能なNormcore Privateがある。
使い方はPhotonに似ているが、クライアント・サーバー方式で、ルームが永続的なデータストアを持っており、データストアを更新することで位置同期等をする仕組みになっている。これにより、ルームから全員出てまた入ってきても状態が維持されている。
Cloud Infrastructureのページを見るとパブリッククラウドがUS East / US West / Europe Westだけに見えるが、公式Discordでの開発者の書き込みによるとアジアリージョン(中国ではない)があるらしい。
トランスポートはWebRTCのみを使用している(扱いが困難なものの、音声やブラウザ対応を含めさまざまな面で優位だからとのこと)。
WebGLビルドに対応予定。現在ベータ版としてエンタープライズユーザーのみに提供されている。
モノビットエンジン
ネットワークサービスとして利用できるモノビットエンジンクラウドがある。
Strix Cloud
Fish-Net
SmartFoxServer
イタリアのGotoAndPlay社のゲームネットワークサービス。
近くのプレイヤーにだけネットワークメッセージを送るArea of Interestをサポートしており、MMOが可能。
ゲームサーバーを自作する
MagicOnion
ピュアC#でゲームサーバーを作る際にメッセージ通信に用いられるフレームワーク。クライアント(Unity側)とサーバーを両方C#で書くことができる(neueccさんが提唱されている「C#大統一理論」)。
- Cysharp/MagicOnion: Unified Realtime/API framework for .NET platform and Unity.
- Building the Game Server both API and Realtime via c#
- 運用中タイトルでも怖くない! 『メルクストーリア』におけるハイパフォーマンス・ローコストなリアルタイム通信技術の導入事例
gRPCを基盤として用いている。ただし、gRPCではProtocol Buffersの.protoファイルをスキーマとして用いるが、MagicOnionはC#のインターフェースを利用する。gRPCがHTTP/2で動いているのでTCP通信のみ。
ソーシャルVRプラットフォームではバーチャルキャストが採用。
gRPC
HTTP/2上でProtocol Buffersで定義したAPIを使ってクライアント・サーバー間でメソッドを呼んだりするフレームワーク。MagicOnionが基盤として用いている。C#以外でゲームサーバーを書くならgRPCを使う場合がありそう。
下記ページによればRust、Go、C#、C++あたりが速いらしい。
Protocol Buffers
Googleが開発した、言語中立なシリアライズ・デシリアライズの仕組み。IDL(インタフェース記述言語)となる.protoファイルでプロトコルを定義し、protocコマンドで各言語のシリアライズ・デシリアライズ用コードを生成することで、異なる言語間で共通するデータのやり取りができるようになる。
上記チュートリアルをやればどういうものか分かります。
ボイスチャット
Photon Voice
VRChatが使用している。
Photon Voice 2をインポートしてApp IDを入力し、DemoVoiceシーンあたりを再生すればオーケー。PUNと組み合わせたデモもある(DemoVoicePun-Sceneシーン)。導入がめちゃくちゃ簡単。
Photon Voice Network、Recorder、Speaker、さらにPUNのネットワークプレハブのSpeakerをリモートのRecorderにバインドするPhoton Voice Viewが主要コンポーネント。
Photon Voice自体は必ずしもPUNと一緒に使う必要はなく、単独でも使える。その場合、Window > Photon Voice > Remove PUN、Remove Photon ChatでPUNやPhoton Chatのアセットを削除して軽量化できる。
WebGLビルドには非対応。PUN上でボイスチャットを行うPUN2VoiceWebGLUnityというのが見つかりますが……(Photonネットワークに音声等のデータを流してはいけないような文言をどこかで見た気が)。
PUNとPhoton Voiceを併用する場合、それぞれの料金がかかります(一般にはダッシュボードでPUNとPhoton VoiceのAppを登録してそれぞれのApp Idを使用します。共通のApp Idを使用すると2倍のCCUになるようです)。
Vivox
PUBGやLeague of Legends、Second Life等が使用しています。Unityに買収されました。5000 PCU(ピーク同時接続ユーザー数)まで無料で、5001 PCUからいきなり$2000/月になります(もうちょっと緩やかな料金体系にしてほしいという書き込み)。
現在、UnityのVivoxフォーラムが公式サポートフォーラムになっています。
WebGLビルドはサポートしていません。2022年2月時点でサポート予定なしとの公式の回答があります。サポートをして欲しい方はこの回答にlikeをつけましょう!
Agora
Clubhouseがボイスチャットに使用していることで話題になりました(Clubhouse自体はすでにJanus WebRTC Serverに切り替えているそうです)。UnityのSDKもあります。
本家の料金表では月10000分まで無料+シンプルな従量課金制なのですが、日本から利用する場合は代理店を通す必要があり、初期費用やアプリごとの月額基本料金がかかってきます。これがかなり高額なので、個人や小規模開発者の選択肢には入らないと思います(なんとかして欲しい)。
Tencent Game Multimedia Engine (GME)
未評価です。Vivoxと同系統の印象?
CRI TeleXus
Dissonance Voice Chat
いろんなネットワークソリューション上にボイスチャットを追加するアセットです。
WebRTC for Unity
上に挙げたものとはカテゴリが違いますが一応ここへ。Unity公式のlibwebrtcベースのWebRTCパッケージがあります。
ゲームサーバーホスティング
AWS等のクラウドでゲームサーバーをホスティングする際、ランニングコストがかかるので、多数のサーバーを常時立ち上げっぱなしにしておくことはできません(特にプレイヤーが大きく増えたり減ったりする場合)。プレイヤーの参加に応じて自動的に新しいサーバーを立ち上げたりシャットダウンするためのサービスやソフトウェアがあります。
マネージドサービス
Amazon GameLift
Unityでビルドした実行ファイルをアップロードして、カスタムゲームサーバーとして実行・オートスケーリングできるサービスです。費用はOn-Demandで一番安い2仮想コアのc5.large 1インスンタンスが$50/月くらい(スポットインスタンスなら数分の1になる)。WindowsサーバーはLinuxサーバーの数倍の費用がかかるので、通常はLinuxビルドしたサーバーを使うことになりそうです。
- ゲーム向けマネージドサービス「Amazon GameLift 」とは何か? 開発・運用コストを削減する、便利な使い方
- UnityでGameLiftを完全攻略 その1 概要編 – soy-software
- UnityでGameLiftを完全攻略 その2 公式サンプル編 – soy-software
- UnityでGameLiftを完全攻略 その3 MLAPI統合編 – soy-software
サーバーのSDK(GameLift Managed Servers SDK)をビルドしてDLLをUnityのプロジェクトに組み込む必要があります。com.unity.nuget.newtonsoft-jsonがコンフリクトする問題が起きていますが、Version Controlパッケージをアンインストールすればオーケー。
Multiplay(Unity)
Apex Legends、Fall Guys等が使用。
Azure PlayFab (Microsoft)
ツール
Kubernetes
Agones
BaaS(Backend as a Service)
ユーザー認証等、多くのゲームやアプリで使用されるバックエンド機能を提供しているサービスがあります。
Unity Gaming Services
2021年10月よりオープンベータとして提供され、2022年6月に正式にサービスインしました。Unity公式サービスなので今後主力になってくる可能性があります。
料金表はこちら。
Firebase(Google)
Firebase Authenticationがユーザー認証に特によく使用されている。UnityのSDKがある。
AndroidではUnityのSDKはGoogle Playサービスが必要なので、Google PlayサービスのないQuestでは注意(REST APIを使用すれば行けるとのこと)。
Azure PlayFab(Microsoft)
GameSparks(Amazon)
NCMB(ニフティ)
Epic Online Services
NAT越えのP2P通信やボイスチャット等が無料で使えるらしい。けど、Unityだと現時点では情報や実績が少なくかなり苦労しそう(Unreal Engineに移行してしまう手が)。
(2021年8月)Unityのプラグインの提供が開始された。
Steam
Valveのマルチプレイヤー機能一式が提供されています。
Oculus
Quest限定ですが、プラットフォームサービスとしてボイスチャット(4人程度まで)やクラウドストレージ等が提供されています。
通信プロトコル
TCP vs UDP
TCPは信頼性のある通信を行うためのプロトコルですが、パケットロスが発生するとパケットの再送が行われ、後続のパケットが届くまで通信が途絶えてしまい(Head-of-line blockingといいます)、ゲームのリアルタイム通信では問題になることがあります。高頻度の位置同期や音声通信、Wi-Fi経由の通信等、パケットロスを気にせずに新しい情報をどんどん送ってほしいというケースではUDPが使われる場合があります。
UDPの上に信頼できる通信を行うレイヤーを作るということがよく行われており(Reliable UDP)、LiteNetLib等のライブラリがあります。
HTTP/2
HTTP/3
QUIC
ブラウザのネットワークAPI
ブラウザでは素のTCP・UDP通信ができず、主に以下のAPIを用いてリアルタイム通信を行います。UnityのWebGLビルドにおいてもこの制限がかかってくるため意識する必要があります。
WebSocket
ブラウザでのリアルタイム通信に使用されます。RFC 6455で定義されたTCP上で双方向通信をするためのWebSocketプロトコルがあり、ブラウザで使用できるWebSocket APIがあります。名前から誤解しやすいですが、通常のソケット通信とは別物です。
WebRTC
クライアント間で音声やビデオをP2Pで通信するためのプロトコル。DataChannelでデータも送れる。UDPを使用。
Unity公式のWebRTCパッケージがあり、P2P通信にはこれが使用できる。直接疎通できない場合が少なからずあり、TURNサーバーが必要になる。オープンソースだとcoturnあたり。
さらにSFUを使用して実質サーバー・クライアント方式に近い通信形態にすることが多い。
WebTransport
現在仕様策定中の新API。WebSocketと同じような要領でUDP通信が可能になるため期待されています。iOS Safariが対応するかどうかが鍵でしょうか(Chrome Platform StatusのConsensus & Standardizationでは現在「No signal」)。
Unityでのマルチプレイヤー開発の効率化
マルチプレイヤーのゲームを開発する際に、一つのプロジェクトファイルを複数のUnityエディタで再生できると便利です。Windowsでは下のようにmklinkコマンドでプロジェクトのフォルダのジャンクションを張ることで、同一のプロジェクトを複数のUnityで開くことができます。
mklink /J Assets %1\Assets
mklink /J Library %1\Library
mklink /J ProjectSettings %1\ProjectSettings
これを簡単にするParrelSyncというエディタ拡張があります。パッケージをインストールしてParrelSync > Clones Managerからプロジェクトを手軽にクローン・削除できます。
また、Unite 2023.1以降ではUnity公式のMultiplayer Play ModeでParrelSyncと同様のことができます。使い方は、com.unity.multiplayer.playmode からパッケージをインストールして、Window > Multiplayer Play Modeを開き、Player 2/3/4のチェックを入れて有効になるのを待ちます。Library/VPフォルダの下にプロジェクトのクローンが作られます。Assets、Packages、ProjectSettingsフォルダあたりで完結するプロジェクトでなければ動きません。
参考資料
以下φ(..)メモメモ中