Unityで手軽にP2P通信を実現!WebRTCベースのMistNetライブラリ紹介
概要
P2P通信とは、Peer to Peer通信の略で、端末同士が直接通信を行うことを指す。
MistNetは、開発者がP2P通信をより手軽に扱えるようにすることを目的として開発した。
Unityでの使用を想定している。
WebRTCをベースにしており、GameObjectの位置、Animation、RPC、変数の同期などを可能とする。
WebRTCについて
WebRTCではP2P型またはSelective Forwarding Unit (SFU) で利用されることが多い。
SFUはサーバーを経由する方式であり、音声や映像をサーバーを経由することで多くのユーザーに配信することができる。
本ライブラリは、P2P型の通信を行う。
WebRTCをUnityで利用できるパッケージが公開されていたため、こちらを利用することにした。
P2P通信を行うには、NAT越えの技術が必要。
これは、STUN/TURNサーバーを使用して、プライベートIPアドレスを持つデバイスが直接通信を行えるようにする。
Network Address Translation (NAT)とは、プライベートIPアドレスをグローバルIPアドレスに変換することを指す。
STUNサーバーによって、自身がサーバーに接続した際のグローバルIPアドレスとポート番号を知ることができる。
TURNサーバーは、直接通信ができない場合に、通信を中継するサーバーである。
接続方式の情報を交換するために、Signalingを行う。
Signalingとは、P2P通信を確立するために必要な情報交換を行うプロセス。
具体的には、WebRTCのOffer、Answer、Candidateをやり取りすることで、直接通信が可能になる。
これを行うために、Signalingのプログラムの作成を行った。
内容としては単純で、WebRTCにおける、Offer、Answer、Candidateを交換するだけである。
誰かのOfferが自身に来た場合、そのOfferを基にしたAnswerを返す。
その間にCandidateを交換する。
MistNetの処理の流れ
まずは管理するObjectにIDを付与し、権限の設定を行う。
権限とは誰がそのObjectのOwnerであるかである。
次に、座標やアニメーションの同期、RPCを用いたイベント実行を通じて、ゲーム内の状態をリアルタイムに他のユーザーに反映させる。
Objectを生成する
- 管理する際のIDを付与
Objectの権限の設定
- 所有権、操作権限
Objectの同期
- 座標
- アニメーション
Objectの状態やイベント実行
- 変数の同期
- Remote Procedure Call (RPC)
作成したライブラリのプログラム例
状態が変化したとき
例えば、ゲーム内でプレイヤーのHPが減少した際、その状態を他のプレイヤーにも反映させるために、以下のように記述する。
[MistSync]
int hp { get; set; }
hpを直接変更すると、他のユーザーにも自動的に通知される。
記述方法については、既存のネットワークライブラリを参考にしている。
RPC
登録方法
[MistRpc]
をメソッドの前につけます。
[MistRpc]
void RPC_○○ () {}
呼び出し方法
[SerializeField] MistSyncObject syncObject;
// 自身を含めた全員に送信する方法
syncObject.RPCAll(nameof(RPC_○○), args);
// 接続しているPeer全員に送信する方法
syncObject.RPCOther(nameof(RPC_○○), args);
// 送信先のIDを指定して実行する方法
syncObject.RPC(id, nameof(RPC_○○), args);
変数の同期
[MistSync]
をつけることで、変数の同期が可能。
[MistSync]
int hp { get; set; }
同期のタイミングは、ユーザーが新しく参加した時と、値が変更時に自動的に行われます。
また、同期時に、任意のメソッドを実行することも可能。
[MistSync(OnChanged = nameof(OnChanged))]
int hp { get; set; }
void OnChanged();
MistNet
MistNetはまだ開発初期段階であり、バグや改善の余地があるかもしれない。
Issueの報告やPull Requestを歓迎する。
Discussion