チャットルーム内の制御

目次

  概要
  ルーム内のプレイヤー一覧の取得
  RPCによる情報の送信
  RPCによる情報の受信
  受信した情報の表示
  ここまでのChatScriptの内容


概要

チャットルーム内の機能を作ってみる

  ここではチャットルーム内での各種制御について、MUN クライアントの主要機能に触れながら組み込んでみましょう。


ルーム内のプレイヤー一覧の取得

ルーム内のプレイヤー一覧を表示する

  ChatScript の 22 行目付近から、以下のコードを記述します。
ルーム内のプレイヤー一覧を表示する
22
23
24
25
26
27
28
29
// ルーム内のプレイヤー一覧の表示
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 行目付近から、以下のコードを記述します。
チャット発言文を保持する変数を宣言する
11
12
13
/** チャット発言文. */
private string chatWord = "";
  GUIを使って入力するチャット発言文を保持する、string 型の変数を用意します。

チャットGUIを作成する

  ChatScript の 34 行目付近から、以下のコードを記述します。
チャットGUIを作成する
34
35
36
37
38
39
// チャット発言文の入力
GUILayout.BeginHorizontal();
GUILayout.Label("Message : ");
chatWord = GUILayout.TextField(chatWord, GUILayout.Width(400));
GUILayout.EndHorizontal();
  前述までと同様、Unityで通常用いる GUILayout を使ってチャット発言文の入力処理を行ないます。

チャット発言文を送信する

  ChatScript の 40 行目付近から、以下のコードを記述します。
チャット発言文を送信する
40
41
42
43
44
45
46
47
48
// チャット発言文を送信する
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 以降であればすでに含まれていますので、書いても書かなくとも構いません)
List を利用するための using ディレクティブを追加する
2
using System.Collections.Generic;
  後述の発言ログ(List<T>)を利用するための using ディレクティブを追加します。

チャット発言ログを保持する変数を宣言する

  さらに ChatScript の 14 行目付近から、以下のコードを記述します。
チャット発言ログを保持する変数を宣言する
14
15
16
/** チャット発言ログ. */
List<string> chatLog = new List<string>();
  GUIを使って入力するチャット発言ログを保持する、List<string> 型の変数を用意します。

チャット発言文を受信し、発言ログに追加する

  ChatScript の 17 行目付近から、以下のコードを記述します。
チャット発言文を受信し、発言ログに追加する
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
 * 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 行目付近から、以下のコードを記述します。
chatLog の内容を表示する
66
67
68
69
70
71
72
// チャットログを表示する
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 の内容は以下の通りです。
ChatScript.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
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");
            }
        }
    }
}