これだけは抑えてきたいMonobit Unity Networking(MUN)の基礎知識【モノビットエンジン入門】

#はじめに
ひと昔前まではオンライン開発というと、サーバ構築などのインフラ知識や、ネットワーク通信の深い理解がないとできないものでした。
そして個人でオンラインゲームを開発しようともなれば、サーバを作るだけで数年かかってしまうことがしばしばでした。
しかし近年、Unityのオンライン開発に特化した**Monobit Unity Networking**が登場し、つい最近では**モノビットエンジンクラウド**がリリースされ、昔と比べるとオンライン開発の敷居が劇的に下がりました。

そんな、ますます勢いを見せるモノビットエンジンですが、存在は知っているけど使ったことがない人、これから使ってみたいけど何から手を付けていいのか分からない人が多くいらっしゃるかと思います。そんな方々にモノビットエンジンの便利さを伝えたいと思いました。
( もっと深く知りたい！という方はぜひ公式リファレンスのチュートリアルをやってみることをお勧めします。)

というわけで、今回はMonobit Unity Networking(MUN)を使うために最低限知っておきたいことをいくつかご紹介したいと思います。

#ざっくりどんな感じなの？
はじめて知った方もいると思うので、**ざっくりと概要を抑えたい方**は下記の記事を見ればだいたい分かると思います。

**導入に関する手順**については下記のリンクをご覧ください。(公式のサンプルを動かすところまでを順を追って解説しています。)
・[モノビットエンジンクラウドでリアルタイム通信のオンラインゲームを作る：準備編](https://qiita.com/nisoka/items/78e6b4d609f25289024a)

**サーバ接続・ルーム入退室**については下記のリンクをご覧ください。
・[モノビットエンジンでかんたんサーバ接続](https://qiita.com/nisoka/items/a7dfe4fad2e0b201ecaa)

**実践的なコードが見たい**という方は下記のリンクをご覧ください。
・[Monobit Unity Networkingを使ってネットワークマネージャクラスを作る【モノビットエンジン入門】](https://qiita.com/nisoka/items/c86a941d6e2c1e2b1e0b)

#最低限知っておきたいこと
さて、ここからは使う上では知っておきたいMUNの基礎知識を紹介していきたいと思います。
###MonobitViewコンポーネント
>**MUNにおける「通信の基盤」**
MonobitView は、「RPCメッセージ通信」や「オブジェクト同期の監視」など、具体的に通信によって実現したい「各クライアント間の情報共有」を支援する、MUN のシステム上極めて重要なコンポーネントです。このコンポーネントをアタッチしているオブジェクトに追加されたスクリプト上で、MonobitView クラスの任意のメソッドを呼び出すことが出来ます。

要するに、オブジェクトが通信を行うならこのコンポーネントを追加すればよいという事です。

コンポーネントの追加方法はこちらのページで解説しています。
参考：[MonobitViewコンポーネント-MUN公式リンク](http://www.monobitengine.com/doc/mun/)

###MonobitViewID
>**MonobitView ID とは？**
ゲームシーン上で「同期通信を行なうオブジェクト」を識別するためのIDです。例えば、「オブジェクト同期」を行なうとした場合、同期情報の送信側と受信側とで「IDの一致したオブジェクト」に対し、位置・姿勢・アニメーション情報を適合させる、などに用います。

つまり、MonobitViewコンポーネントを追加されたオブジェクトに割り振られた一意の名前みたいなものです。
ひとつ注意点として、1プレイヤーにつき最大1000個までしか割り振れません。
後述しますが、RPCメッセージを送り合えるのは、同じMonobitViewIDを持っている者同士だけです。

###MunRPC
>**任意の情報を通信するための手段**
RPCとは「Remote Procedure Call（リモートプロシージャコール）」の略で、簡単に説明すると、ネットワーク上にある、別のクライアント端末のメソッドを呼び出す仕組みのことです。MUN では、ネットワーク通信を使って、端末間で情報をやり取りする場合、RPC を用いて実行します。

MonobitEngineが使いやすく改良したRPCメッセージです。
注意点として、MonobitViewコンポーネントが必要、MonobitEngine.MonoBehaviourの継承が必要、ルーム入室している必要があります。
最低限この３つを知っていればメッセージが送られてこないということは起きないはずです。
参考：[RPC(Remote Procedure Call)-MUN公式リンク](http://www.monobitengine.com/doc/mun/)

###コールバックメソッド
>**MUNサーバとの通信状況を知るためのコールバックメソッド**
MUNサーバに接続し、様々なネットワーク機能を使う中で、いくつかの例外に遭遇するケースが考えられます。例えば、サーバ接続に失敗したり、ネットワーク断線による途中切断だったり、その種類は少なくありません。また、単なる「サーバに接続している / いない」だけではなく、より詳細の、例えば「作成しようとしたルームと同名のルームがあり、ルーム作成に失敗した」り、「ルーム入室しようとしたが、どのルームも満員で入室できなかった」り、そういった例外も存在します。

リアルタイム通信では要求を出したそのフレームでは結果が返ってきません。
例えば、クライアントがサーバへ接続の要求を出す場合だと、サーバがクライアントに接続処理完了の返答をするまで何フレームかかかる訳です。大雑把に言うと、各処理に対するサーバからの返答があったときに呼ばれるメソッドがコールバックメソッドです。

注意点として、MonobitEngine.MonoBehaviourの継承が必要です。
参考：[接続コールバック-MUN公式リンク](http://www.monobitengine.com/doc/mun/)

#次のステップ
上の４つを理解できたら次に知っておきたい項目です。
###ネットワークオブジェクトの生成
>**プレハブ/アセットバンドルを用いたインスタンス生成を「ネットワーク上で同期」させて実行する**
プレハブまたはアセットバンドルをもとにインスタンス生成を行なう Unity のメソッドとして、UnityEngine.Instantiate や UnityEngine.CreateAssetBundle（UnityEngine.LoadAssetBundle） などがありますが、これはあくまでローカル上でのインスタンス生成であり、ネットワーク越しに生成するためには、それなりのプロセスが必要です。MUN では、ネットワークの垣根を超えて同時にインスタンス生成するための、インタフェースを用意しています。

要するに、自分が生成したオブジェクトが同じルームにいる他のプレイヤー画面にも登場させられますよという事です。
ただし、生成方法はいままでと違い、MonobitNetwork.Instantiateという拡張メソッドを使います。
注意点としては、MonobitViewコンポーネントをアタッチする必要、ルーム入室している必要があります。
参考：[ネットワーク越しのオブジェクトの生成-MUN公式リンク](http://www.monobitengine.com/doc/mun/)

###オブジェクトの所有権
>**ネットワーク越しにインスタンスを生成したオブジェクトには「所有権」が存在する**
MonobitEngine.MonobitNetwork.Instantiate メソッド、ならびに、MonobitEngine.MonobitNetwork.InstantiateSceneObject メソッドを用いてインスタンス生成されたオブジェクトには、サーバからプレイヤーに対し「所有権」が与えられます。

つまり、ネットワークオブジェクトは生成した人が所有権を握ります。さらに言えば破棄までの責任を負います。

>**ネットワーク越しに生成されたオブジェクトを「操作」する場合、その「所有権」が存在するかどうかチェックする必要がある**
所有権をチェックせずにオブジェクトを動かそうとすると、他人のキャラクタも操作してしまいます。ネットワーク通信同期においては、自分自身が作成した（所有権を持っている）キャラクタのみを操作するというチェックを掛けたうえでオブジェクトを操作する必要があります。

所有者がなぜ重要なのかというと、他人のプレイヤーが自分の画面に登場したときに、これがあるおかげで自分と他人を同時に操作することを防げるからです。
参考：[オブジェクト所有権チェック-NUM公式リンク](http://www.monobitengine.com/doc/mun/)

#最後に
やや駆け足ではありましたが、最低限知っておきたい知識は以上です。
まだ「なんのこっちゃ」という方はチュートリアルを終えてから、改めてもう一度読んでみるときっと理解が深まると思います。
他にもMUNに関する記事を書いているのでよかったらそちらもどうぞ。

#MUN関連記事
**かんたんなPinpong対戦ゲーム**を作った記事はこちらです

- [モノビットエンジンでリアルタイム通信のオンラインゲームを作る：座標同期を行う](https://qiita.com/nisoka/items/b6064946f3184f85d323)
- [モノビットエンジンでリアルタイム通信のオンラインゲームを作る：ボールを跳ね返す](https://qiita.com/nisoka/items/e00b15d42084d768dd21)

**リアルタイムシューティングゲーム**を作った記事はこちらです

- [【Unity】オンラインシューティングゲームを作る：弾の処理](https://qiita.com/nisoka/items/a10cddec1e108dc41e58)
- [【Unity】オンラインシューティングゲームを作る：敵をつくる](https://qiita.com/nisoka/items/ab49ab381c9fac05afb5)

**機能**に関する記事はこちらです

- [【Unity】入室可能なルームが存在するかチェックする方法【モノビットエンジン入門】](https://qiita.com/nisoka/items/9f5ec0868d2bbe00b476)
- [モノビットエンジン版 RPCメッセージを使いパラメータ同期をおこなう](https://qiita.com/nisoka/items/b75c07a0f0240414e9e5)