チャットルーム内の制御
目次
概要
ルーム内のプレイヤー一覧の取得
RPCによる情報の送信
RPCによる情報の受信
受信した情報の表示
ここまでのChatScriptの内容
チャットルーム内の機能を作ってみる
ここではチャットルーム内での各種制御について、MUN クライアントの主要機能に触れながら組み込んでみましょう。
ルーム内のプレイヤー一覧の取得▲
ルーム内のプレイヤー一覧を表示する
ChatScript の 22 行目付近から、以下のコードを記述します。
// ルーム内のプレイヤー一覧の表示
GUILayout.BeginHorizontal();
GUILayout.Label("PlayerList : ");
foreach(MonobitPlayer player in MonobitNetwork.playerList)
{
GUILayout.Label(player.name + " ");
}
GUILayout.EndHorizontal();
MonobitNetwork.playerList は、現在入室しているルーム内に存在するプレイヤーについて、その一覧を配列情報で格納されています。
データ型は MonobitPlayer[] 型で、上記の例では foreach() にて要素を1つずつ player に取得し、
その中に含まれる MonobitPlayer.name を使って「プレイヤー名の一覧」を表示させています。
RPCによる情報の送信▲
チャット発言文を保持する変数を宣言する
ChatScript の 11 行目付近から、以下のコードを記述します。
/** チャット発言文. */
private string chatWord = "";
GUIを使って入力するチャット発言文を保持する、string 型の変数を用意します。
チャットGUIを作成する
ChatScript の 34 行目付近から、以下のコードを記述します。
// チャット発言文の入力
GUILayout.BeginHorizontal();
GUILayout.Label("Message : ");
chatWord = GUILayout.TextField(chatWord, GUILayout.Width(400));
GUILayout.EndHorizontal();
前述までと同様、Unityで通常用いる GUILayout を使ってチャット発言文の入力処理を行ないます。
チャット発言文を送信する
ChatScript の 40 行目付近から、以下のコードを記述します。
// チャット発言文を送信する
if (GUILayout.Button("Send", GUILayout.Width(100)))
{
monobitView.RPC("RecvChat",
MonobitTargets.All,
MonobitNetwork.playerName,
chatWord);
chatWord = "";
}
[Send] ボタンを押したときに、RPCを使ってメッセージを送信します。
RPC については こちら を御参照ください。
今章の最初に追加された MonobitViewコンポーネント を用いて、MonobitView.RPC() メソッドをコールします。
(ソース内に記された monobitView は、MonobitViewコンポーネント本体を取得するプロパティです。)
MonobitView.RPC() メソッドにより、ルーム内のすべてのクライアントに対して、
・ MonobitNetwork.playerName - 自身のプレイヤー名
・ chatWord - チャット会話文として入力した文字列
を送信します。
RPCによる情報の受信▲
System.Collections.Generic の using ディレクティブを追加する
Unity2018.2 以下のバージョンをお使いの場合、ChatScript の 2 行目付近に、以下のコードを記述します。
(Unity2018.3 以降であればすでに含まれていますので、書いても書かなくとも構いません)
using System.Collections.Generic;
後述の発言ログ(List<T>)を利用するための using ディレクティブを追加します。
チャット発言ログを保持する変数を宣言する
さらに ChatScript の 14 行目付近から、以下のコードを記述します。
/** チャット発言ログ. */
List<string> chatLog = new List<string>();
GUIを使って入力するチャット発言ログを保持する、List<string> 型の変数を用意します。
チャット発言文を受信し、発言ログに追加する
ChatScript の 17 行目付近から、以下のコードを記述します。
/**
* RPC 受信関数.
*/
[MunRPC]
void RecvChat(string senderName, string senderWord)
{
chatLog.Add(senderName + " : " + senderWord);
if( chatLog.Count > 10 )
{
chatLog.RemoveAt(0);
}
}
MonobitView.RPC() メソッドを使って送信された情報の受信メソッドを定義します。
このメソッドの定義要件は以下の通りです。
・メソッド名の接頭に[MunRPC]のアトリビュートを付記すること。
・MonobitView.RPC() メソッド の第1引数と同じ名前のメソッド名で定義すること。
・MonobitView.RPC() メソッド の第3引数以降に対応するデータ型の引数値を定義すること。
今回の場合、MonobitView.RPC() メソッド の第1引数に "RecvChat" を指定していましたので、 メソッド名を
RecvChat() として定義します。
また、MonobitView.RPC() メソッド の第3引数以降に ( string, string ) 型のデータを指定していますので、
RecvChat() の引数値も (string, string) のデータ型で一致させます。
処理内で行なっていることは、至って単純で、"送信者名 : 送信文書"の形式で chatLogに後方追加し、
chatLog に追加された件数が10件を超えたら、List の先頭を削除する、という処理を行なわせます。
受信した情報の表示▲
chatLog の内容を表示する
ChatScript の 67 行目付近から、以下のコードを記述します。
// チャットログを表示する
string msg = "";
for(int i = 0; i < 10; ++i )
{
msg += ((i < chatLog.Count) ? chatLog[i] : "") + "\r\n";
}
GUILayout.TextArea(msg);
chatLog を msg にまとめ、GUILayout.TextArea() で表示させます。
ここまでのChatScriptの内容▲
改めて触れますが、ここまでのChatScript.cs の内容は以下の通りです。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using MonobitEngine;
public class ChatScript : MonobitEngine.MonoBehaviour
{
/** ルーム名. */
private string roomName = "";
/** チャット発言文. */
private string chatWord = "";
/** チャット発言ログ. */
List<string> chatLog = new List<string>();
/**
* RPC 受信関数.
*/
[MunRPC]
void RecvChat(string senderName, string senderWord)
{
chatLog.Add(senderName + " : " + senderWord);
if (chatLog.Count > 10)
{
chatLog.RemoveAt(0);
}
}
/**
* GUI制御.
*/
void OnGUI()
{
// MUNサーバに接続している場合
if (MonobitNetwork.isConnect)
{
// ルームに入室している場合
if (MonobitNetwork.inRoom)
{
// ルーム内のプレイヤー一覧の表示
GUILayout.BeginHorizontal();
GUILayout.Label("PlayerList : ");
foreach (MonobitPlayer player in MonobitNetwork.playerList)
{
GUILayout.Label(player.name + " ");
}
GUILayout.EndHorizontal();
// チャット発言文の入力
GUILayout.BeginHorizontal();
GUILayout.Label("Message : ");
chatWord = GUILayout.TextField(chatWord, GUILayout.Width(400));
GUILayout.EndHorizontal();
// チャット発言文を送信する
if (GUILayout.Button("Send", GUILayout.Width(100)))
{
monobitView.RPC("RecvChat",
MonobitTargets.All,
MonobitNetwork.playerName,
chatWord);
chatWord = "";
}
// チャットログを表示する
string msg = "";
for (int i = 0; i < 10; ++i)
{
msg += ((i < chatLog.Count) ? chatLog[i] : "") + "\r\n";
}
GUILayout.TextArea(msg);
}
// ルームに入室していない場合
else
{
// ルーム名の入力
GUILayout.BeginHorizontal();
GUILayout.Label("RoomName : ");
roomName = GUILayout.TextField(roomName, GUILayout.Width(200));
GUILayout.EndHorizontal();
// ルームを作成して入室する
if (GUILayout.Button("Create Room", GUILayout.Width(150)))
{
MonobitNetwork.CreateRoom(roomName);
}
// ルーム一覧を検索
foreach (RoomData room in MonobitNetwork.GetRoomData())
{
// ルームパラメータの可視化
System.String roomParam =
System.String.Format(
"{0}({1}/{2})",
room.name,
room.playerCount,
((room.maxPlayers == 0) ? "-" : room.maxPlayers.ToString())
);
// ルームを選択して入室する
if (GUILayout.Button("Enter Room : " + roomParam))
{
MonobitNetwork.JoinRoom(room.name);
}
}
}
}
// MUNサーバに接続していない場合
else
{
// プレイヤー名の入力
GUILayout.BeginHorizontal();
GUILayout.Label("PlayerName : ");
MonobitNetwork.playerName = GUILayout.TextField(
(MonobitNetwork.playerName == null) ?
"" :
MonobitNetwork.playerName, GUILayout.Width(200));
GUILayout.EndHorizontal();
// デフォルトロビーへの自動入室を許可する
MonobitNetwork.autoJoinLobby = true;
// MUNサーバに接続する
if (GUILayout.Button("Connect Server", GUILayout.Width(150)))
{
MonobitNetwork.ConnectServer("SimpleChat_v1.0");
}
}
}
}