teratail header banner
teratail header banner
質問するログイン新規登録

質問編集履歴

1

文法の修正

2020/05/11 14:31

投稿

uiuiko
uiuiko

スコア9

title CHANGED
File without changes
body CHANGED
@@ -1,101 +1,220 @@
1
1
  [このサイトを見ながらやっています。](http://uniblo.biz/unity/mmogame/chapter8_chat)
2
2
  PhotonNetWorkingを使ってチャット機能を作っています。
3
3
  元からあった "InRoomChat"を改良して近くにいるキャラクターと全体に表示されるチャットに分けたいのです。
4
+
4
- のコードやじr
5
+ 変更後のコード
5
- ```c#
6
+ ```c#
6
7
  using System.Collections.Generic;
7
8
  using UnityEngine;
8
9
  using System.Collections;
9
-
10
10
  [RequireComponent(typeof(PhotonView))]
11
11
  public class InRoomChat : Photon.MonoBehaviour
12
12
  {
13
+ #region 変数宣言
14
+ //範囲チャット実装のためのオブジェクト、変数定義
15
+ GameObject[] players; //全てのプレイヤーキャラ取得用
16
+ GameObject sender; //送信キャラ取得用
17
+ GameObject myPlayer; //自分のキャラ取得用
18
+ GUIStyle ChatStyle = new GUIStyle(); //範囲チャットStyle
19
+ GUIStyleState ChatStyleState = new GUIStyleState();
20
+ GUIStyle AllChatStyle = new GUIStyle(); //全体チャットStyle
21
+ GUIStyleState AllChatStyleState = new GUIStyleState();
13
- public Rect GuiRect = new Rect(0,0, 250,300);
22
+ public Rect GuiRect = new Rect(0, 0, 300, 200); //チャットUIの大きさ設定用
14
- public bool IsVisible = true;
23
+ public bool IsVisible = true; //チャットUI表示非表示フラグ
15
- public bool AlignBottom = false;
24
+ public bool AlignBottom = true;
16
- public List<string> messages = new List<string>();
25
+ public List<string> messages = new List<string>(); //チャットログ格納用List
26
+ public List<bool> chatKind = new List<bool>(); //チャットログの種類格納用(範囲チャor全チャ)
17
- private string inputLine = "";
27
+ public string inputLine = "";//入力文章格納用String
18
- private Vector2 scrollPos = Vector2.zero;
28
+ private Vector2 scrollPos = Vector2.zero; //スクロールバー位置
19
-
29
+ #endregion
20
- public static readonly string ChatRPC = "Chat";
30
+ #region Start関数 Updata関数
21
-
22
31
  public void Start()
23
32
  {
33
+ //myPlayerオブジェクト取得(範囲チャット発言時にpositionとmyPM使う)
24
- if (this.AlignBottom)
34
+ GetmyPlayer();
25
- {
35
+ //範囲チャットの場合は白文字にし、文字がUIからあふれた場合は折り返す設定
26
- this.GuiRect.y = Screen.height - this.GuiRect.height;
36
+ ChatStyleState.textColor = Color.white;
37
+ ChatStyle.normal = ChatStyleState;
27
- }
38
+ ChatStyle.wordWrap = true;
39
+ //全体チャットの場合は赤文字にし、文字がUIからあふれた場合は折り返す設定
40
+ AllChatStyleState.textColor = Color.red;
41
+ AllChatStyle.normal = AllChatStyleState;
42
+ AllChatStyle.wordWrap = true;
28
43
  }
29
-
44
+ public void Update()
45
+ {
46
+ //ChatUIの位置を調整
47
+ this.GuiRect.y = Screen.height - this.GuiRect.height;
48
+ //ChatUIの大きさ調整
49
+ GuiRect.width = Screen.width / 3;
50
+ GuiRect.height = Screen.height / 3;
51
+ }
52
+ #endregion
53
+ #region OnGUI関数
30
54
  public void OnGUI()
31
55
  {
32
- if (!this.IsVisible || !PhotonNetwork.inRoom)
56
+ if (!this.IsVisible || !PhotonNetwork.inRoom) //表示フラグがOFFまたはphotonにつながっていないとき
33
57
  {
58
+ //UI非表示
34
59
  return;
35
60
  }
36
-
61
+ //ChatUIの作成開始
62
+ //チャットUI生成 Begin&EndAreaでチャットUIの位置と大きさを設定
63
+ GUILayout.Window(0, GuiRect, ChatUIWindow, ""); //チャットUIウインドウを作成
64
+ //Enterを押すと
37
65
  if (Event.current.type == EventType.KeyDown && (Event.current.keyCode == KeyCode.KeypadEnter || Event.current.keyCode == KeyCode.Return))
38
66
  {
67
+ //チャット入力待ち状態にする
68
+ GUI.FocusControl("ChatInput");
69
+ }
70
+ }
71
+ #endregion
72
+ #region チャットUI生成
73
+ void ChatUIWindow(int windowID)
74
+ {
75
+ //FocusがチャットUIに乗ってるときにEnterを押すとチャット発言が実行される
76
+ if (Event.current.type == EventType.KeyDown && (Event.current.keyCode == KeyCode.KeypadEnter || Event.current.keyCode == KeyCode.Return))
77
+ {
39
- if (!string.IsNullOrEmpty(this.inputLine))
78
+ if (!string.IsNullOrEmpty(this.inputLine)) //チャット入力欄がNullやEmptyでない場合
40
79
  {
41
- this.photonView.RPC("Chat", PhotonTargets.All, this.inputLine);
42
- this.inputLine = "";
43
- GUI.FocusControl("");
80
+ //範囲チャット送信関数実行
44
- return; // printing the now modified list would result in an error. to avoid this, we just skip this single frame
81
+ SendChat(false);
82
+ return;
45
83
  }
46
- else
47
- {
48
- GUI.FocusControl("ChatInput");
49
- }
50
84
  }
51
-
52
- GUI.SetNextControlName("");
85
+ //垂直のコントロールグループ開始
53
- GUILayout.BeginArea(this.GuiRect);
86
+ GUILayout.BeginVertical();
54
-
87
+ //スクロールビュー開始位置
55
88
  scrollPos = GUILayout.BeginScrollView(scrollPos);
89
+ //チャットログ表示用フレキシブルスペース生成
56
90
  GUILayout.FlexibleSpace();
91
+ //フレキシブルスペースにチャットログを表示
57
- for (int i = messages.Count - 1; i >= 0; i--)
92
+ for (int i = 0; i <= messages.Count - 1; i++)
58
93
  {
94
+ if (chatKind[i] != true) //範囲チャットであれば
95
+ {
59
- GUILayout.Label(messages[i]);
96
+ GUILayout.Label(messages[i], ChatStyle);
97
+ }
98
+ else //全チャットであれば
99
+ {
100
+ GUILayout.Label(messages[i], AllChatStyle);
101
+ }
60
102
  }
103
+ //スクロールビュー終了
61
104
  GUILayout.EndScrollView();
62
-
105
+ //水平のコントロールグループ開始
63
106
  GUILayout.BeginHorizontal();
107
+ //入力テキストフィールド生成、Focusが乗った状態をChatInputと命名
64
108
  GUI.SetNextControlName("ChatInput");
65
- inputLine = GUILayout.TextField(inputLine);
109
+ inputLine = GUILayout.TextField(inputLine, 200);
110
+ //「Send」ボタンを生成かつ押したときには範囲チャット送信
66
111
  if (GUILayout.Button("Send", GUILayout.ExpandWidth(false)))
67
112
  {
68
- this.photonView.RPC("Chat", PhotonTargets.All, this.inputLine);
69
- this.inputLine = "";
70
- GUI.FocusControl("");
113
+ //範囲チャット送信関数実行
114
+ SendChat(false);
71
115
  }
116
+ //Allボタンを生成かつ押したときには全体チャット送信
117
+ if (GUILayout.Button("All", GUILayout.ExpandWidth(false)))
118
+ {
119
+ //全体チャット送信関数実行
120
+ SendChat(true);
121
+ }
122
+ //水平のコントロールグループ終了
72
123
  GUILayout.EndHorizontal();
124
+ //垂直のコントロールグループ終了
73
- GUILayout.EndArea();
125
+ GUILayout.EndVertical();
74
126
  }
75
-
127
+ #endregion
128
+ #region GetmyPlayer 自キャラのオブジェクトをmyPlayerに登録
129
+ void GetmyPlayer()
130
+ {
131
+ //自キャラのID取得
132
+ int myPlayerID = PhotonNetwork.player.ID;
133
+ //全てのプレイヤーオブジェクトを取得
134
+ players = GameObject.FindGameObjectsWithTag("Player");
135
+ //全てのプレイヤーオブジェクトから自キャラをIDで検索し、取り出す
136
+ foreach (GameObject player in players)
137
+ {
138
+ int playerLoopId = player.GetComponent<PhotonView>().owner.ID;
139
+ if (playerLoopId == myPlayerID)
140
+ {
141
+ //自プレイヤーオブジェクトを取得
142
+ myPlayer = player;
143
+ }
144
+ }
145
+ return;
146
+ }
147
+ #endregion
148
+ #region チャット送信関数
149
+ void SendChat(bool isAll)
150
+ {
151
+ //chatRPC
152
+ this.photonView.RPC("Chat", PhotonTargets.All, myPlayer.transform.position, this.inputLine, isAll);
153
+ //送信後、入力欄を空にし、スクロール最下位置に移動
154
+ this.inputLine = "";
155
+ scrollPos.y = Mathf.Infinity;
156
+ }
157
+ #endregion
158
+ #region ChatRPC RPC呼出側:送信者 RPC受信側:受信者
76
159
  [PunRPC]
77
- public void Chat(string newLine, PhotonMessageInfo mi)
160
+ public void Chat(Vector3 senderposition, string newLine, bool isAll, PhotonMessageInfo mi)
78
161
  {
162
+ if (messages.Count >= 100) //チャットログが多くなって来たらログを削除してから受信
163
+ {
164
+ messages.Clear(); //全てのチャットログを削除
165
+ chatKind.Clear(); //全てのチャットの種類情報削除
166
+ }
167
+ if (!isAll) //範囲チャとして受信
168
+ {
169
+ //myPlayerとsenderの距離から受信するか判断
170
+ if (Vector3.Distance(myPlayer.transform.position, senderposition) < 10)
171
+ {
172
+ //chat受信
173
+ ReceiveChat(newLine, isAll, mi);
174
+ }
175
+ }
176
+ else if (isAll) //全チャとして受信
177
+ {
178
+ //chat受信
179
+ ReceiveChat(newLine, isAll, mi);
180
+ }
181
+ //受信したときはスクロール最下位置
182
+ scrollPos.y = Mathf.Infinity;
183
+ }
184
+ #endregion
185
+ #region チャット受信関数
186
+ void ReceiveChat(string _newLine, bool isAll, PhotonMessageInfo _mi)
187
+ {
188
+ //送信者の名前用変数
79
189
  string senderName = "anonymous";
80
-
81
- if (mi.sender != null)
190
+ if (_mi.sender != null)
82
191
  {
192
+ //送信者の名前があれば
83
- if (!string.IsNullOrEmpty(mi.sender.NickName))
193
+ if (!string.IsNullOrEmpty(_mi.sender.NickName))
84
194
  {
85
- senderName = mi.sender.NickName;
195
+ senderName = _mi.sender.NickName;
86
196
  }
87
197
  else
88
198
  {
89
- senderName = "player " + mi.sender.ID;
199
+ senderName = "player " + _mi.sender.ID;
90
200
  }
91
201
  }
92
-
202
+ //受信したチャットをログに追加
93
- this.messages.Add(senderName +": " + newLine);
203
+ this.messages.Add(senderName + ": " + _newLine);
204
+ this.chatKind.Add(isAll);
205
+ return;
94
206
  }
95
-
207
+ #endregion
96
208
  public void AddLine(string newLine)
97
209
  {
98
210
  this.messages.Add(newLine);
99
211
  }
100
212
  }
101
- ```
213
+ ```
214
+ ![こちらです](8e50776f16258b30d476ec79f10fd7eb.png)
215
+ inspecterはこうなっています。
216
+
217
+ NullReferenceException: Object reference not set to an instance of an object
218
+
219
+ ↑というエラーが出ます。
220
+ すいません教えてください。