ネットワーク制御スクリプトの作成

目次

  概要
  サーバへの接続
  ルームの作成
  選択式でのルーム入室
  ランダム式でのルーム入室
  ルームからの退室
  サーバからの切断
  プレイヤーキャラクタを登場させる
  ここまでのNetworkControl.csの内容
  変更したプログラムの保存


概要

サーバへの接続からルーム入室までの流れを作る

  オフライン専用のゲームシステムからマルチプレイが可能なオンラインゲームを作成するためには、
  どんなゲームシステムであれ、おおよそ以下の機能を実装する必要があります。
・サーバへの接続
・ルームの作成
・ルームへの入室
・ルームからの退室
・サーバからの切断
  前章まででも触れている上述の内容に加え、今回は
・プレイヤーオブジェクトの出現処理
  もあります。
  「オンライン制御に必要な根幹部分」について一連の機能を作成してみましょう。

【注記】実行ボタンを押しても正常な結果を得られません。

  このページ内容を反映させても、実行ボタンを押して正常な結果は得られません。ご注意ください。


サーバへの接続

サーバに接続し、デフォルトのロビーに入室する

  NetworkControl.cs の 11 行目付近(Start() メソッド内)から、以下のコードを記述します。
		// デフォルトロビーへの自動入室を許可する
		MonobitNetwork.autoJoinLobby = true;

		// MUNサーバに接続する
		MonobitNetwork.ConnectServer("Bearpocalypse_v1.0");
  前章でも触れた復習項目ですが。

  MonobitNetowork.autoJoinLobby = true にすることで、自動的にデフォルトロビーに入室し、
  MonobitNetwork.ConnectServer でMUNサーバに接続します。

  MonobitNetwork.ConnectServer のパラメータは、前章と被らないようにしておくと、
  サーバ内でユーザーを分断してくれます。


ルームの作成

ルーム名を保持する変数を用意する

  NetworkControl の 8 行目付近に、以下の変数を宣言します。
		/** ルーム名. */
		private string roomName = "";
		
  GUIを使って入力するルーム名を保持する、string型の変数を用意します。

GUIを用いて、ルームを作成する

  NetworkControl の 24 行目付近(OnGUI()メソッド内)から、以下のコードを記述します。
		// デフォルトのボタンと被らないように、段下げを行なう。
		GUILayout.Space(24);
		
		// MUNサーバに接続している場合
		if( MonobitNetwork.isConnect )
		{
			// ルームに入室していない場合
			if( !MonobitNetwork.inRoom )
			{
				GUILayout.BeginHorizontal();

				// ルーム名の入力
				GUILayout.Label("RoomName : ");
				roomName = GUILayout.TextField(roomName, GUILayout.Width(200));

				// ボタン入力でルーム作成
				if ( GUILayout.Button("Create Room", GUILayout.Width(150)))
				{
					MonobitNetwork.CreateRoom(roomName);
				}

				GUILayout.EndHorizontal();

			}
		}
  これも前章で触れた復習項目ですが。

  それぞれ MonobitNetwork のプロパティ&メソッドを使って、以下の判定&処理を行ないます。
     ・ MonobitNetwork.isConnect
          → サーバに接続しているかどうかのフラグ。trueなら接続中。falseなら未接続or切断済み。
     ・ MonobitNetwork.inRoom
          → ルームに入室しているかどうかのフラグ。trueなら入室中。falseなら未入室or退室済み。
     ・ MonobitNetwork.CreateRoom
          → 指定したルーム名を持つルームを作成し、入室する関数。

  前章と同様、GUILayout については説明を割愛します。


選択式でのルーム入室

ルーム一覧を取得し、選択したルームに入室する

  NetworkControl の 47 行目付近から、以下のコードを記述します。
                // ルーム一覧から選択式で入室する
                foreach (RoomData room in MonobitNetwork.GetRoomData())
                {
                    string strRoomInfo =
                        string.Format("{0}({1}/{2})",
                                      room.name,
                                      room.playerCount,
                                      (room.maxPlayers == 0) ? "-" : room.maxPlayers.ToString());
                           
                    if (GUILayout.Button("Enter Room : " + strRoomInfo))
                    {
                        MonobitNetwork.JoinRoom(room.name);
                    }
                }
  これも前章で触れた復習項目ですが。

  MonobitNetwork.GetRoomData() メソッドは、現在入室しているロビー内に存在するルームについて、その一覧を取得する命令です。
  戻り値は RoomData[] 型で、上記の例では foreach() にて配列情報を1つずつ room で取得しています。

  RoomData クラスには、ルーム情報としていくつかのデータが含まれています。上記ではその一例として、以下の情報をボタン表示させています。
     ・ RoomData.name - ルーム名
     ・ RoomData.playerCount - 現在入室しているプレイヤー人数
     ・ RoomData.maxPlayers - 入室可能なプレイヤー最大人数(0の場合には無制限)

  また MonobitNetwork.JoinRoom() メソッドは、特定のルームに入室するための命令です。
  パラメータに、そのルームを特定する「ルーム名」を指定します。


ランダム式でのルーム入室

ロビー内のルームの中から、ランダムで選択したルームに入室する

  NetworkControl の 47 行目付近から、以下のコードを記述します。
				// 現在存在するルームからランダムに入室する
				if( GUILayout.Button("Join Random Room", GUILayout.Width(200)) )
				{
					MonobitNetwork.JoinRandomRoom();
				}
				
  MonobitNetwork.JoinRandomRoom() メソッドは、現在入室しているロビー内のルームの中から、
  任意のルームを選択して入室する制御です。


ルームからの退室

現在入室しているルームから退室する

  NetworkControl の 30 行目付近から、以下のコードを記述します。
			// ルームに入室している場合
			if( MonobitNetwork.inRoom )
			{
				// ボタン入力でルームから退室
				if (GUILayout.Button("Leave Room", GUILayout.Width(150)))
				{
					MonobitNetwork.LeaveRoom();
				}
			}
				
  これも前章で触れている復習項目ですが。
  MonobitNetwork.LeaveRoom() メソッドは、現在入室中のルームから退室するための命令です。


サーバからの切断

接続しているサーバから切断し、シーンをリセットする

  NetworkControl の 30 行目付近から、以下のコードを記述します。
            // ボタン入力でサーバから切断&シーンリセット
            if (GUILayout.Button("Disconnect", GUILayout.Width(150)))
            {
                // サーバから切断する
                MonobitNetwork.DisconnectServer();

                // シーンをリロードする
#if UNITY_5_3_OR_NEWER || UNITY_5_3
                string sceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
                UnityEngine.SceneManagement.SceneManager.LoadScene(sceneName);
#else
                Application.LoadLevel(Application.loadedLevelName);
#endif
            }
  MonobitNetwork.DisconnectServer() メソッドは、サーバから切断する命令です。
  切断後、再接続するためには、もう一度 MonobitNetwork.ConnectServer() メソッド のコールが必要です。

  MonobitNetwork.ConnectServer() メソッドは、Start() メソッドで定義していますので、
  シーンをリロードすることにより再接続を可能にしています。
  (それ以外にも、ゲーム離脱後にシーンを初期化する意味を含めてリロードさせます。)


プレイヤーキャラクタを登場させる

プレイヤーキャラクタを保持する変数を用意する

  NetworkControl.cs の 11 行目付近に、以下の変数を宣言します。
	/** プレイヤーキャラクタ. */
	private GameObject playerObject = null;
	
  上記のように、プレハブから生成されたプレイヤーキャラクタの GameObject を保持する変数を用意します。

プレイヤーキャラクタを「全てのクライアントでほぼ同時に」出現させる

  NetworkControl の 24 行目付近から、以下のコードを記述します。
    // Update is called once per frame
    void Update()
    {
        // MUNサーバに接続しており、かつルームに入室している場合
        if (MonobitNetwork.isConnect && MonobitNetwork.inRoom)
        {
            // プレイヤーキャラクタが未登場の場合に登場させる
            if (playerObject == null)
            {
                playerObject = MonobitNetwork.Instantiate(
                                "Player",
                                Vector3.zero,
                                Quaternion.identity,
                                0);
            }
        }
    }
    

  MUNサーバに接続している状態で、かつルームに入室しており、プレイヤーキャラクタが未登場の場合(playerObject にまだ値が設定されていない場合)に、
  MonobitNetwork.Instantiate() メソッドを使い、ネットワーク越しに全てのクライアントに対し、自身のプレイヤーキャラクタを登場させます。

  MonobitNetwork.Instantiate() メソッドは以下のパラメータを持ちます。
第一引数
("Player")
GameObjectとして生成される元データの、プレハブの名前を指定します。
注意すべき点として、読み込み対象となるprefabファイルが、Resources フォルダに存在する必要があります。
第二引数
(Vector3.zero)
GameObjectを出現させる座標値について、Vector3型で指定します。
第三引数
(Quaternion.identity)
GameObjectを出現させるときの回転量について、Quaternion型で指定します。
第四引数
(0)
その GameObject が所属する、MUNネットワーク上のグループIDを指定します。
通常は0を指定します。


ここまでのNetworkControl.csの内容


  改めて触れますが、ここまでの NetworkControl.cs の内容は以下の通りです。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MonobitEngine;

public class NetworkControl : MonobitEngine.MonoBehaviour
{
    /** ルーム名. */
    private string roomName = "";

    /** プレイヤーキャラクタ. */
    private GameObject playerObject = null;

    // Start is called before the first frame update
    void Start()
    {
        // デフォルトロビーへの自動入室を許可する
        MonobitNetwork.autoJoinLobby = true;

        // MUNサーバに接続する
        MonobitNetwork.ConnectServer("Bearpocalypse_v1.0");
    }

    // Update is called once per frame
    void Update()
    {
        // MUNサーバに接続しており、かつルームに入室している場合
        if (MonobitNetwork.isConnect && MonobitNetwork.inRoom)
        {
            // プレイヤーキャラクタが未登場の場合に登場させる
            if (playerObject == null)
            {
                playerObject = MonobitNetwork.Instantiate(
                                "Player",
                                Vector3.zero,
                                Quaternion.identity,
                                0);
            }
        }
    }
    
    // OnGUI is called for rendering and handling GUI events
    void OnGUI()
    {
        // デフォルトのボタンと被らないように、段下げを行なう。
        GUILayout.Space(24);

        // MUNサーバに接続している場合
        if (MonobitNetwork.isConnect)
        {
            // ボタン入力でサーバから切断&シーンリセット
            if (GUILayout.Button("Disconnect", GUILayout.Width(150)))
            {
                // サーバから切断する
                MonobitNetwork.DisconnectServer();

                // シーンをリロードする
#if UNITY_5_3_OR_NEWER || UNITY_5_3
                string sceneName = UnityEngine.SceneManagement.SceneManager.GetActiveScene().name;
                UnityEngine.SceneManagement.SceneManager.LoadScene(sceneName);
#else
                Application.LoadLevel(Application.loadedLevelName);
#endif
            }

            // ルームに入室している場合
            if (MonobitNetwork.inRoom)
            {
                // ボタン入力でルームから退室
                if (GUILayout.Button("Leave Room", GUILayout.Width(150)))
                {
                    MonobitNetwork.LeaveRoom();
                }
            }

            // ルームに入室していない場合
            if (!MonobitNetwork.inRoom)
            {
                GUILayout.BeginHorizontal();

                // ルーム名の入力
                GUILayout.Label("RoomName : ");
                roomName = GUILayout.TextField(roomName, GUILayout.Width(200));

                // ボタン入力でルーム作成
                if (GUILayout.Button("Create Room", GUILayout.Width(150)))
                {
                    MonobitNetwork.CreateRoom(roomName);
                }

                GUILayout.EndHorizontal();

                // 現在存在するルームからランダムに入室する
                if (GUILayout.Button("Join Random Room", GUILayout.Width(200)))
                {
                    MonobitNetwork.JoinRandomRoom();
                }

                // ルーム一覧から選択式で入室する
                foreach (RoomData room in MonobitNetwork.GetRoomData())
                {
                    string strRoomInfo =
                        string.Format("{0}({1}/{2})",
                                      room.name,
                                      room.playerCount,
                                      (room.maxPlayers == 0) ? "-" : room.maxPlayers.ToString());

                    if (GUILayout.Button("Enter Room : " + strRoomInfo))
                    {
                        MonobitNetwork.JoinRoom(room.name);
                    }
                }
            }
        }
    }
}



変更したプログラムの保存

スクリプトを保存する

  ここまでプログラムを組んできた NetworkControl.cs を保存しましょう。
  Visual Studio のメニューから [ファイル] > [すべて保存] を選択してください。