Unityでオンラインマルチプレイなゲームを作りたい その3 サーバー接続

前回でオンラインマルチを作成する準備ができていたので、実際に作っていこうと思います。[前回の記事](https://qiita.com/koyuki2007/items/15bf4cd834722e8b47ab)
内容は記事毎に小分けして書いていこうと思います。

# 最終目標
ローグライク × アクションなゲームをの製作

# 今回の目標
タイトル画面を作成し、スタートボタンでサーバーへ接続する処理を作ります。

# その前に
大まかに今回制作するゲームの画面遷移を状態遷移図にしてみました。
各画面でサーバーへの接続/切断、ルーム作成/入室/退室/といった遷移時に必要な処理も大まかに記入しています。
こういったものを作っておくと実装時にこんがらがることが少なくなります。
今回は画像上の赤い丸で囲ってる部分を実装していこうと思います。
![Untitled Diagram.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469983/78be4d41-bb49-ceff-9f74-e7edcfd055a6.png)
# タイトル画面
※イメージ図(ゲームタイトルが左にずれてますけど気にしないでください)
![キャプチャ4444444444444444444.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469983/32efcdf1-0bde-c3f0-7f4c-4d420adcacb9.jpeg)
このイメージを元にタイトル画面を作っていこうと思います。
※UI等の作成手順は簡略して書くか諸々端折ります。

#### タイトル画面制御
タイトル画面を制御するコードを書いていきます。
※uGUI系はプレハブ化しています。

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

public class SceneTitle : MonoBehaviour
{
    // UIを表示するキャンバス
    private GameObject m_CanvasObj;

    // タイトルテキスト
    private GameObject m_TitleTxtObj;

    // スタートボタン
    private GameObject m_StartBtnObj;

    // 終了ボタン
    private GameObject m_ExitBtnOnj;


    // Start is called before the first frame update
    void Start()
    {
        // UIを表示するためのキャンバス
        m_CanvasObj = Instantiate(Resources.Load("Canvas")) as GameObject;

        // タイトルテキスト表示
        m_TitleTxtObj = Instantiate(Resources.Load("Text")) as GameObject;
        m_TitleTxtObj.transform.SetParent(m_CanvasObj.transform);
        m_TitleTxtObj.transform.localPosition = new Vector3(72.0f, 128.0f, 0.0f);
        m_TitleTxtObj.GetComponent<Text>().text = "Game Title";

        // スタートボタンの作成
        m_StartBtnObj = Instantiate(Resources.Load("Button")) as GameObject;
        m_StartBtnObj.transform.SetParent(m_CanvasObj.transform);
        m_StartBtnObj.transform.localPosition = new Vector3(0.0f, -80.0f, 0.0f);
        m_StartBtnObj.GetComponent<Button>().GetComponentInChildren<Text>().text = "Start";
        m_StartBtnObj.GetComponent<Button>().onClick.AddListener(OnClickStart);

        // 終了ボタンの作成
        m_ExitBtnOnj = Instantiate(Resources.Load("Button")) as GameObject;
        m_ExitBtnOnj.transform.SetParent(m_CanvasObj.transform);
        m_ExitBtnOnj.transform.localPosition = new Vector3(0.0f, -180.0f, 0.0f);
        m_ExitBtnOnj.GetComponent<Button>().GetComponentInChildren<Text>().text = "Exit";
        m_ExitBtnOnj.GetComponent<Button>().onClick.AddListener(OnClickExit);
    }

    // Update is called once per frame
    void Update()
    {
        
    }

    // スタートボタンが押された際に行いたい処理
    private void OnClickStart()
    {

    }

    // 終了ボタンが押された際に行いたい処理
    private void OnClickExit()
    {
#if UNITY_EDITOR
        UnityEditor.EditorApplication.isPlaying = false;

#elif UNITY_STANDALONE
        UnityEngine.Application.Quit();
#endif
    }
}
```
uGUIを配置してボタンにクリック時に呼び出してほしい関数を定義しているだけですね。

#### サーバー接続
では、MUNを使ってサーバーへ接続する処理を実装していきます。

まずは公式のドキュメントでサーバーの接続方法を見てみます。
http://www.monobitengine.com/doc/mun/contents/FeatureClient/ConnectToServer.htm

```c# 
MonobitEngine.MonobitNetwork.ConnectServer();
```
この関数を呼ぶだけでサーバーへ接続できそうです。
![キャプチャ.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469983/d96368a1-5e4f-2c00-ac94-bb58f402dcc6.jpeg)
この接続コールバックというものを利用することで接続されたかどうか等の確認が行えるみたいです。

ということで先ほどのコードにサーバー接続処理と接続コールバックを加えていきます。
※変更点以外の部分は省いて記載しています。

```c#

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using MonobitEngine; // MUNの機能を使うために追加します

public class SceneTitle : MonobitEngine.MonoBehaviour // 接続コールバックを利用するために、
{                                                     // UnityEngineではなくMonobitEngineのMonoBehaviourを利用する
    // スタートボタンが押された際に行いたい処理
    private void OnClickStart()
    {
        // スタートボタンが押されたときにサーバーへ接続させたい
        // 引数にはゲームのバージョンをいれてあげるといいです
        MonobitEngine.MonobitNetwork.ConnectServer("DungeonAction_v_1_0");
    }

   // MUNサーバーとの接続に成功した際に呼ばれる接続コールバック
    public void OnConnectedToMonobit()
    {
        Debug.Log("接続しました");
    }

    // サーバから切断したときに呼ばれる接続コールバック
    public void OnDisconnectedFromServer()
    {
        Debug.Log("切断しました");
    }

    // MUNサーバーとの接続に失敗した際に呼ばれる接続コールバック
    public void OnConnectToServerFailed(MonobitEngine.DisconnectCause cause)
    {
        Debug.Log("接続に失敗しました:" + cause.ToString());
    }

    // MUNサーバーとの接続後に何らかの原因で切断されたときに呼ばれる接続コールバック
    public void OnConnectionFail(MonobitEngine.DisconnectCause cause)
    {
        Debug.Log("サーバーとの接続後に何らかの原因で切断されました:" + cause.ToString());
    }

    // サーバーへの接続数が上限だった際に呼ばれる接続コールバック
    public void OnMonobitMaxConnectionReached()
    {
        Debug.Log("サーバーに接続しているクライアント数が上限に達しています");
    }
}
```
上記コードに変更後、実行してStartボタンを押すと「接続しました」とConsoleに出力されます。
![キャプチャ2222.JPG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/469983/752ce786-fcc3-30a9-a906-1f690c80508f.jpeg)
なお、接続が成功した状態で終了ボタンを押すと「切断しました」と表示されます。
アプリケーション終了時に自動で切断してくれているみたいです。

サーバーへ接続できるようになりました。
次回はロビー画面とロビー入室の作成を行いたいと思います。

# 資料
http://www.monobitengine.com/doc/mun/
http://www.monobitengine.com/doc/mun/contents/FeatureClient/ConnectToServer.htm