ネットワーク制御スクリプトの作成
目次
概要
サーバへの接続
ルームの作成
選択式でのルーム入室
ランダム式でのルーム入室
ルームからの退室
サーバからの切断
プレイヤーキャラクタを登場させる
ここまでの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 のメニューから [ファイル] > [すべて保存] を選択してください。