Unityでオンラインマルチプレイなゲームを作りたい その4 ロビー入室

[前回の記事](https://qiita.com/koyuki2007/items/247c13603244020f6bb8)でサーバーへ接続できるようになったので、次の段階であるロビーへの入室を作成します。
# 今回の目標
前回の状態遷移図的には画像上の赤〇で囲っている辺りを作っていきます。
![Untitled Diagram_2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469983/18906d8d-9bd7-c61c-7a64-1881481b6d02.png)
イメージ図
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469983/48bf0081-d187-e813-4abd-da41fcf6a62f.jpeg)

# ロビー
http://www.monobitengine.com/doc/mun/contents/Reference/Glossary.htm#%E3%83%AD%E3%83%93%E3%83%BC
特定の条件でルーム群を分けるものとかそういうイメージでいいのでしょうか。
スプラのレギュラーマッチとガチマッチ的な感じで大きく分けるときに使うと良さそうかもです。
今回は特にロビーを複数作る理由が無いので、デフォルトのロビーを使っていこうと思います。

## ロビー入室処理
デフォルトのロビーへ入室する処理を追加します。
http://www.monobitengine.com/doc/mun/contents/FeatureClient/AutoJoinLobby.htm

```c#
MonobitEngine.MonobitNetwork.autoJoinLobby = true;
```
このコードをMonobitNetwork.ConnectServer()を呼ぶ前に追加するだけでデフォルトのロビーへ入室してくれます。
ということで追加してみます。
※変更点があったところ以外は割愛

```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using MonobitEngine;

public class SceneTitle : MonobitEngine.MonoBehaviour
{
    // スタートボタンが押された際に行いたい処理
    private void OnClickStart()
    {
        // 自動でデフォルトのロビーへ入室する
        MonobitNetwork.autoJoinLobby = true;

        // スタートボタンが押されたときにサーバーへ接続させたい
        // 引数にはゲームのバージョンをいれてあげるといいです
        MonobitEngine.MonobitNetwork.ConnectServer("DungeonAction_v_1_0");
    }
}
```
これでロビーへ入室できます。

ロビー入室成功直後で処理を行えるように更にソースを変更していきます。
http://www.monobitengine.com/doc/mun/contents/FeatureClient/CallbackFunction.htm

```c#
public void OnJoinedLobby()
```
この関数を追加するだけでロビー入室直後の処理を実装できそうです。
※<code>MonobitNetwork.autoJoinLobby</code>を<code>true</code>にしていると<code>OnConnectedToServer()</code>が呼ばれなくなり、代わりに<code>OnJoinedLobby()</code>が呼ばれるようになっているため、<code>OnConnectedToServer()</code>で実装している内容は<code>OnJoinedLobby()</code>に移しましょう。

```c#
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using MonobitEngine;

public class SceneTitle : MonobitEngine.MonoBehaviour
{
    // スタートボタンが押された際に行いたい処理
    private void OnClickStart()
    {
        // 自動でデフォルトのロビーへ入室する
        MonobitNetwork.autoJoinLobby = true;

        // スタートボタンが押されたときにサーバーへ接続させたい
        // 引数にはゲームのバージョンをいれてあげるといいです
        MonobitEngine.MonobitNetwork.ConnectServer("DungeonAction_v_1_0");
    }

     /// <summary>ロビーへ入室した際に呼ばれるコールバック</summary>
     private void OnJoinedLobby()
     {
        // ロビー入室に成功したのでロビー画面へ切り替える
        SceneManager.LoadScene("Lobby");
     }
}
```
ロビーへ入室後にロビー画面へ切り替えることが出来るようになりました。

## ロビー画面
ボタン毎にシーンを切り替える機能と、タイトル画面へ戻る際に、サーバー切断を行う機能を実装します。
#### ロビーへ入室できているかを確認
http://www.monobitengine.com/doc/doxygen/client/html/class_monobit_engine_base_1_1_monobit_network.html#ab4b92a64b1b2657f1eda9332186c721c
![キャプチャ2.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469983/d9721a8b-8c8e-28c0-8244-aece5cf53f1e.jpeg)

```c#
bool MonobitEngineBase.MonobitNetwork.inLobby
```
ロビーへ入室している状態かをこれで確認できます。
ロビー入室がされていない状態では行ってほしくない処理などを制限するのに使えますね。

#### サーバーから切断
http://www.monobitengine.com/doc/mun/contents/FeatureClient/DisconnectFromServer.htm

```c#
MonobitEngine.MonobitNetwork.DisconnectServer();
```
サーバーから切断を行うにはこれを使います。

```c#
void OnDisconnectedFromServer()
```
<code>DisconnectServer()</code>が呼ばれた後に呼ばれる関数です。
サーバー切断後に行いたい処理はこの中に書きます。


上記の機能たちを踏まえてロビー画面制御を作成していきます。
※uGUIの実装は省いてます。

```c#
/// <summary>ロビー入室後の画面</summary>
public class SceneLobby : MonobitEngine.MonoBehaviour
{
    // Start is called before the first frame update
    private void Start()
    {
        // ロビーへの入室が成されているかを確認する
        if(!MonobitNetwork.inLobby)
        {
            Debug.Log("Not in lobby");
            return;
        }

        /*-------------------------------ロビー画面変更後のuGUI配置などの処理-----------------------------*/
    }

    /// <summary>MUNサーバーとの接続を切った際に呼ばれるコールバック</summary>
    private void OnDisconnectedFromServer()
    {
        // サーバーから切断された後にタイトル画面に戻るようにする
        SceneManager.LoadScene("Title");
    }

    /// <summary>ルーム作成画面へ移動するボタンを押した際に呼ばれる</summary>
    private void OnClickCreateRoom()
    {
        SceneManager.LoadScene("CreateRoom");
    }

    /// <summary>ルーム入室画面へ移動するボタンを押した際に呼ばれる</summary>
    private void OnClickJoinRoom()
    {
        SceneManager.LoadScene("JoinRoom");
    }

    /// <summary>タイトル画面へ戻るボタンを押した際に呼ばれる</summary>
    private void OnClickBack()
    {
        // サーバーから切断する
        MonobitNetwork.DisconnectServer();
    }
}
```
これでロビー画面で必要な機能は実装できました。

次回はルームを作成する画面を作っていこうと思います。

# 資料
http://www.monobitengine.com/doc/mun/contents/Reference/Glossary.htm#%E3%83%AD%E3%83%93%E3%83%BC
http://www.monobitengine.com/doc/mun/contents/FeatureClient/AutoJoinLobby.htm
http://www.monobitengine.com/doc/mun/contents/FeatureClient/CallbackFunction.htm
http://www.monobitengine.com/doc/doxygen/client/html/class_monobit_engine_base_1_1_monobit_network.html#ab4b92a64b1b2657f1eda9332186c721c