Slide 1

Slide 1 text

新MLAPI(v0.1.0)で マルチゲームを作ってみた gotanda unity #19 Lighting Talk

Slide 2

Slide 2 text

自己紹介 【名前 / Twitter】 Denik / @xrdnk 【職歴】 TIS 株式会社 19年度入社 インキュベーションセンター XR 新規事業開発チーム XR(VR/AR/MR) エンジニア 弊社のXRソリューションサービス 「XR Campus」シリーズの開発に従事しています. 本発表は個人の見解です. 所属組織の意見云々ではありません.

Slide 3

Slide 3 text

MLAPI Quick Start Mirror の Quick Start を 新 MLAPI に対応したサンプルを作りました. 脳死で以下の記事通りに行えば,このようなマルチプレイゲームを作ることが出来ます. MLAPI v0.1.0 Quick Start サンプルプロジェクトを作成しました https://xrdnk.hateblo.jp/entry/2021/03/26/185500

Slide 4

Slide 4 text

アジェンダ ➢ MLAPI について ➢ 旧 MLAPI と 新 MLAPI の違い ➢ Refactored API Names ➢ MLAPI の機能紹介 ➢ 同期用コンポーネント群 ➢ NetworkManager ➢ NetworkBehaviour ➢ NetworkVariable ➢ RPC ➢ Custom Messaging Manager ➢ Transport Layer ➢ おわりに

Slide 5

Slide 5 text

MLAPI について

Slide 6

Slide 6 text

MLAPI (v0.1.0) 2020.12 に Unity が買収した GameObject 向けの公式マルチプレイヤーソリューション 2021.3 末に MLAPI の新しいバージョン(v0.1.0)が Experimental Release

Slide 7

Slide 7 text

MLAPI 採用例 TIS の 「XR Campus ツアーサービス トライアル版」で現在採用中 (宣伝ではありません) https://www.tis.jp/service_solution/xr_campus/tour/

Slide 8

Slide 8 text

旧 MLAPI と 新 MLAPI の違い

Slide 9

Slide 9 text

リリースノート リリースノートがあります. (弊ブログの日本語化記事) https://xrdnk.hateblo.jp/entry/2021/03/23/192000 新機能,変更点,修正点,既知の問題が載っています. 大方は旧 MLAPI の機能がそのまま使われていますが,結構最適化されていたりしています. 詳細を知りたい方はリリースノートを参照ください.

Slide 10

Slide 10 text

Refactored API Names 変更点のうち,API や Script Component の名前変更が結構されています.(20箇所以上) もし旧 MLAPI から新 MLAPI にアップグレードする際は結構修正が必要になります. 例) 1. -ed / -ing (過去分詞/現在分詞) が削除されたもの NetworkingManager → NetworkManager, NetworkedObject → NetworkObject NetworkedBehaviour → NetworkBehaviour, NetworkedClient → NetworkClient etc. 2. Network が頭についたもの Transport → NetworkTransport, Channel → NetworkChannel etc. 3. 置換されたもの BitStream / BitReader / BitWriter → NetworkBuffer / NetworkReader / NetworkWriter NetworkVar → NetworkVariable, ChannelType → NetworkDelivery

Slide 11

Slide 11 text

MLAPI の機能紹介

Slide 12

Slide 12 text

同期用コンポーネント群 同期用コンポーネント 機能 注意点 NetworkObject 同期するオブジェクトに付与 1オブジェクトに1つのみの制限 NetworkTransform Transformの同期 Scaleの同期は出来ない. PositionとRotationのみ. NetworkAnimator Animatorの同期 Triggerの同期は出来ない. Bool,Float, Intのみ. スクリプト側で同期させるAnimatorを 動的に設定する場合,致命バグがある ため,個人的にはAnimatorの同期を行 う場合はNetworkAnimatorを採用せ ずに,RPCを利用するのが吉だったり. NetworkNavMeshAgent NavMeshAgentの同期 以下は同期されない. Mesh Data,Agent Size,Steering, Obstacle Avoidance,Path Finding Settings. destinationとvelocityの同期のみで 目的地までの経路の同期は行わない.

Slide 13

Slide 13 text

NetworkManager MLAPI の管理クラス ネットワーク関連の設定,同期用のプレハブ設定,シーン設定,接続管理等を行う (ちなみに v0.1.0 現在, NetworkManager は Singleton 構造になっているため,Server to Server 通信は現状至難の業だったりする.) プロパティ 内容 IsClient クライアントかどうか IsHost ホストかどうか(= IsClient && IsServer) IsServer サーバかどうか IsLocalPlayer ローカルプレイヤーかどうか IsOwnedByServer サーバが所有権を持つかどうか メソッド 内容 StartServer/StopServer サーバを起動/終了する StartHost/StopHost ホストを起動/終了する StartClient/StopClient クライアントを起動/終了する DisconnectClient 指定クライアントを切断する コールバック 内容 OnServerStarted サーバ起動時 OnClientConnected クライアント接続時 OnClientDisconnected クライアント切断時 ConnectionApprovalCheck 接続許可確認時

Slide 14

Slide 14 text

NetworkBehaviour 同期させるスクリプトコンポーネントは NetworkBehaviour を継承する必要がある 後述する NetworkVariable や RPC は NetworkBehaviour を継承することで利用できる プロパティ 内容 IsClient クライアントかどうか IsHost ホストかどうか(= IsClient && IsServer) IsServer サーバかどうか IsLocalPlayer ローカルプレイヤーかどうか IsOwnedByServer サーバが所有権を持つかどうか

Slide 15

Slide 15 text

NetworkVariable (1)|利用可能な型 変数の同期に利用する.利用可能な型は以下の通り. ➢ C# プリミティブ型 ex) bool, int, ulong, float, double, string ➢ Unity プリミティブ型 ex) Color, Color32, Vector2/3/4, Quaternion, Ray, Ray2D ➢ Enum 型 C#/Unity プリミティブ型の場合,ジェネリクス版だけでなく, [Serializable]な各々のNetworkVariable専用の型が存在する (Inspectorで表示したい場合は後者の方を利用するとよい)

Slide 16

Slide 16 text

NetworkVariable (2)|SerializationManager 自分で作ったクラスや構造体の型の場合,2通りの対応方法があります. ① SerializationManager.RegisterSerializationHandlers を利用する方法

Slide 17

Slide 17 text

NetworkVariable (3)| INetworkSerializable ② INetworkSerializable インタフェースを実装する方法 INetworkSerializable を実装して, NetworkSerialize メソッドに Serialize 処理を 記述するだけでよくなります. ①の方法では後述する RPC には対応できませんが, ②の方法ならRPCも対応できます. ①の方法で対応するとRPC利用時に以下のエラーが出ます. 一応欠点としては, INetworkSerializableをインタフェースと して持つのが必須になります.①の場合は持たなくてよいです.

Slide 18

Slide 18 text

NetworkVariable (4)|NetworkVariableSettings ➢ NetworkVariableSettings NetworkVariableに書込・読込権限,チャネル設定を行う 項目 内容 WritePermission 書き込み権限 ReadPermission 読み込み権限 SendTickrate 変数が同期される1秒当たりの最大回数 SendChannel チャネル設定

Slide 19

Slide 19 text

NetworkVariable (5)|Value ➢ Value Value プロパティを通して値の読取,設定を行う 前回と同じ値を設定した場合は何も変化しない (UniRxのReactiveProperty.Valueと同じ感じです)

Slide 20

Slide 20 text

NetworkVariable (6)|OnValueChanged ➢ OnValueChanged NetworkVariable の値が変化した時にコールバック(フック関数)を登録出来る

Slide 21

Slide 21 text

RPC (1) ネットワーク上に接続されたほかの端末のプログラムを呼び出して実行する. マルチプレイでよく使われる手法かと思います. [ServerRpc] ClientがServerにお願いする [ClientRpc] ServerがClientにお願いする Client Client Server

Slide 22

Slide 22 text

RPC (2)|ServerRpc/ClientRpc 新 MLAPI では 「普通のメソッド呼び出し」の要領で RPC 呼び出しを行うことが出来る (旧MLAPIだと InvokeClientRpc(RpcMethod()) と書かないと RPC 呼び出しができなかった)

Slide 23

Slide 23 text

RPC (3)|ServerRpcParams/ClientRpcParams Rpcメソッドのパラメタに ServerRpcParams / ClientRpcParams を オプションとして加えることができ,送信先の絞り込み等ができます. 以下はClientRpcを呼び出す際に受信する対象クライアントを 「自分以外のクライアント」に絞り込んでいる例です.

Slide 24

Slide 24 text

NetworkVariable と RPC の使い分け 以下,MLAPI のドキュメントより抜粋. RPC vs NetworkVariable https://docs-multiplayer.unity3d.com/docs/learn/rpcvnetvar NetworkVariables are great for managing state, to make sure everyone has the latest value. Use them when you want to make sure newly connected players get an up to date world state. NetworkVariablesはステートの管理に最適で,全員が最新の値を持っていることを確認できます. 新しく接続されたプレイヤーが最新のワールドステートを取得できるようにしたい場合に使用します. RPCs are great for sending transient events. Use them when transmiting short lived events. RPCは一過性のイベントを送るのに適しています.短時間のイベントを送信するときに使用します. 後から入ってきたプレイヤーにこの値は同期させる必要があるのか?を考えるといいです. 例えばプレイヤーの名前は後から入ってきたプレイヤーでも把握する必要がありますが, 入室前に発生したイベント(ジャンプやエモート等)は後から入ってきたプレイヤーは知る必要がありません. 永続的に同期する変数はNetworkVariable,短期的な同期イベントはRPCを利用する感じでしょうか.

Slide 25

Slide 25 text

Custom Messaging Manager (1)|使いどころ NetworkVariable や RPC は NetworkObject を持ち, NetworkBehaviour を継承したクラスではないと利用できない → NetworkObject 所持 ・ NetworkBehaviour 継承の継承がなくても同期処理を行いたい → Custom Messaging Manager を利用する Photon の RaiseEvent に近しい機能です. Photon でも RPC を利用する際は PhotonView が必要ですよね. 以降,4ページに渡って CustomMessagingManagerを利用した Client → Server → Client の同期方法を説明していますが, 時間の関係上,ここでは巻き気味にします.後程スライドをご覧ください.

Slide 26

Slide 26 text

Custom Messaging Manager (2)|フロー ① メッセージをClientが書込 Serverに向けて送信 ③ ②のメッセージをServerが書込 対象Clientに向けて送信 Client Client ② Client からの①メッセージ受信 Server が読込 ④ Server からの③メッセージを受信 Client が読込

Slide 27

Slide 27 text

Custom Messaging Manager (3)|Client → Server クライアント側がサーバ側に向けてメッセージを送る ◆ サーバ送信用のストリームを作る ◆ ストリームにメッセージを書き込む ◆ ◆ ストリームにデータを載せて送信

Slide 28

Slide 28 text

Custom Messaging Manager (4)|Server → 全Client (1) サーバ側が送られてきたメッセージを受信して,さらに対象クライアントに向けてメッセージを送る処理 ◆ クライアントから送られてきたストリームを受信 ◆ ストリームにあるデータを読み込む ◆ クライアント送信用のストリームを作る ◆ ストリームにデータを書き込む ◆ ストリームを送る

Slide 29

Slide 29 text

Custom Messaging Manager (5)|Server → 全Client(2) クライアント側がサーバから送られてきたメッセージを読み込む ◆サーバから送られてきたストリームを受信 ◆ストリームにあるデータを読み込む

Slide 30

Slide 30 text

Custom Messaging Manager (6)|受信処理の登録・解除 Custom Message を受信する処理 (②と④の処理) ここでは事前に Awake の中で登録する必要があります 送信側の処理はメソッドを叩くイメージ.受信側の処理は事前登録するイメージ.

Slide 31

Slide 31 text

Transport Layer (1) MLAPI でデフォルトで搭載されている NetworkTransport に UNetTransport があります プロトタイプ程度のレベルだったら UNetTransport で済ませてもいいかもしません 安定を求める場合は, MLAPI.Contribution から以下の Transport 層が提供されています. Template が提供されているので, Template に沿えば Transport 層の自作は勿論可能です. (WebSocketSharp 版を作ったりすることができます) トランスポート名 対応プラットフォーム Ruffles Desktop/Mobile Enet Desktop/Mobile LiteNetLib Desktop/Mobile SteamP2P Steam PhotonRealtime Desktop/Mobile/WebGL https://github.com/Unity-Technologies/mlapi-community-contributions

Slide 32

Slide 32 text

Transport Layer (2)| iOS 審査裏話 ちなみにオンラインマルチプレイゲームをiOSリリースする時に罠があるのをご存じでしょうか. UDP 通信だと実は Apple 審査にリジェクトされます.(MLAPI だけでなく, Photon や Mirror も同様) どうやら Apple の環境では UDP は通さない模様(コロナになってから?) 対応方法として, Apple 審査用に TCP 通信に切り替えられる処理を作る方法が挙げられます. https://developer.apple.com/forums/thread/133938 (R)UDP通信のマルチプレイアプリはiOS審査でリジェクトされる - デニッキ! https://xrdnk.hateblo.jp/entry/2021/07/18/230017

Slide 33

Slide 33 text

終わりに

Slide 34

Slide 34 text

サンプル集 ➢ 公式サンプル ➢ Boss Room v 0.2.1 | 結構情報量が多くて,重い https://github.com/Unity-Technologies/com.unity.multiplayer.samples.coop/releases/tag/v0.2.1 ➢ BiteSize Sample v 0.1.0 | 小さいサンプル.手始めにこっちからやるのもよい https://github.com/Unity-Technologies/com.unity.multiplayer.samples.bitesize ➢ 作ったサンプル ➢ MLAPI Quick Start | Mirror Quick Start を 新 MLAPI に対応 (紹介しているコードはここから抜粋) https://github.com/xrdnk/MLAPI-QuickStart ➢ その他サンプル ➢ MLAPI UnityChan Sample | Unityの黒河さん作 Relay Server や Headless Server の繋ぎ方に関する説明が記載されている https://github.com/wotakuro/MLAPI_UnitychanSample/tree/unity2020.3

Slide 35

Slide 35 text

ドキュメント集 ➢ 公式ドキュメント ➢ Unity Multiplayer Networking | 基本ここを見ればいい https://docs-multiplayer.unity3d.com/ ➢ その他 ➢ デニッキ! | 私のブログです https://xrdnk.hateblo.jp/archive/category/MLAPI ➢ Dapper-Dino Tutorials| YouTubeで説明がされています(英語) https://docs-multiplayer.unity3d.com/docs/learn/dapper/dapper-video