WEBVTT 1 00:00:28.200 --> 00:00:30.200 Hello, this is Youngho Lee 2 00:00:30.200 --> 00:00:33.800 In this lecture, we will learn about chat, essential for communication 3 00:00:33.800 --> 00:00:39.000 between players when playing network multiplayer games 4 00:00:39.000 --> 00:00:42.700 What we will learn is first creating a chat UI 5 00:00:42.700 --> 00:00:45.400 and then implementing chat logic 6 00:00:45.400 --> 00:00:50.400 You can quickly create a chat by applying the actor replication you learned earlier 7 00:00:50.400 --> 00:00:52.500 First, let's create the chat UI 8 00:00:53.018 --> 00:00:55.918 Create Chat UI 9 00:00:59.000 --> 00:01:01.799 Now, let’s create a chat UI 10 00:01:03.799 --> 00:01:06.400 The chat UI will be expressed like this 11 00:01:06.400 --> 00:01:12.700 If you look at the screen, the UI is expressed like this at the bottom left 12 00:01:12.700 --> 00:01:16.200 The message is sent 13 00:01:16.200 --> 00:01:19.900 when the user enters a message using the chat UI 14 00:01:19.900 --> 00:01:22.099 created in this way and presses the send button 15 00:01:22.099 --> 00:01:27.000 The transmitted form looks like this: 16 00:01:27.000 --> 00:01:31.500 this is the current server, the left is the server, and the right is the current client 17 00:01:31.500 --> 00:01:34.040 When there are two clients and a server 18 00:01:36.020 --> 00:01:40.000 the user is the client, just like chat and other things 19 00:01:40.000 --> 00:01:42.740 This client sends a message to the server 20 00:01:43.500 --> 00:01:47.099 When sent, it is sent in Server RPC format 21 00:01:47.099 --> 00:01:48.699 So, if there is not just one client 22 00:01:48.699 --> 00:01:51.099 but Client 1 and Client2 23 00:01:51.099 --> 00:01:53.199 when the client sends a message to the server 24 00:01:53.199 --> 00:01:56.500 the server receives it and broadcasts it 25 00:01:56.500 --> 00:01:58.600 This is what we send to all clients 26 00:02:00.400 --> 00:02:03.460 At this time, there may be several ways 27 00:02:04.299 --> 00:02:06.500 First, we can use Server RPC 28 00:02:06.500 --> 00:02:10.000 and as we did before, use multicast 29 00:02:10.000 --> 00:02:12.599 to send it using NetMulticast 30 00:02:12.599 --> 00:02:16.699 Then, the message will be sent to all users 31 00:02:16.699 --> 00:02:19.000 It will appear on the screen like this 32 00:02:19.000 --> 00:02:20.480 There may be a way like this 33 00:02:21.800 --> 00:02:25.099 Another case is when you do not use multicast 34 00:02:25.099 --> 00:02:28.399 but only Client RPC 35 00:02:29.699 --> 00:02:32.199 Similarly, the client sends a message 36 00:02:32.199 --> 00:02:35.319 to the server using Server RPC like this 37 00:02:36.399 --> 00:02:38.000 Then, the server receives this 38 00:02:38.000 --> 00:02:41.600 and sends it to the clients using Client RPC 39 00:02:41.600 --> 00:02:43.000 How does this work? 40 00:02:43.000 --> 00:02:47.620 In the case of the server, since it has PlayerControllers 41 00:02:49.000 --> 00:02:51.899 it has PlayerControllers for all players 42 00:02:51.899 --> 00:02:55.000 so the server can send messages 43 00:02:55.000 --> 00:02:58.539 to this client and then to this client 44 00:02:59.399 --> 00:03:01.020 You can also handle it like this 45 00:03:01.500 --> 00:03:03.699 There can be many ways 46 00:03:03.699 --> 00:03:07.060 We first configure the UI 47 00:03:07.060 --> 00:03:08.060 We will even 48 00:03:09.460 --> 00:03:11.800 implement the logic 49 00:03:11.800 --> 00:03:14.199 to display such content 50 00:03:14.199 --> 00:03:15.699 using multicast or clients 51 00:03:15.699 --> 00:03:20.019 We will be creating this part to create a chat UI 52 00:03:21.899 --> 00:03:24.500 To do this, go to Unreal Editor 53 00:03:24.500 --> 00:03:28.660 and when you come to Unreal Editor, you can create UI 54 00:03:29.500 --> 00:03:31.239 I'll go to the UI folder 55 00:03:33.899 --> 00:03:38.159 and right-click to create a User Widget 56 00:03:38.159 --> 00:03:39.699 so that the chat UI can be displayed 57 00:03:39.699 --> 00:03:41.280 on the screen 58 00:03:43.740 --> 00:03:45.159 Widget Blueprint 59 00:03:45.899 --> 00:03:49.779 Then, the classes that need to be inherited appear here 60 00:03:50.399 --> 00:03:52.619 A message created in the chat window 61 00:03:52.619 --> 00:03:55.800 will be sent and processed as follows 62 00:03:55.800 --> 00:03:59.399 There is a User Widget to handle this 63 00:03:59.399 --> 00:04:02.600 You can create a separate C++ class later 64 00:04:02.600 --> 00:04:05.439 then register it as a parent class and use it 65 00:04:06.419 --> 00:04:08.699 We will create the UI first 66 00:04:08.699 --> 00:04:11.079 then create a C++ class 67 00:04:12.259 --> 00:04:17.140 and make that class its parent class 68 00:04:20.000 --> 00:04:23.100 Now, first, click User Widget 69 00:04:23.100 --> 00:04:29.720 and name it WBP_ChatMsg 70 00:04:31.300 --> 00:04:33.899 The MSG Widget Blueprint 71 00:04:33.899 --> 00:04:37.600 called WBP_ChatMsg, is 72 00:04:37.600 --> 00:04:39.799 currently creating a User Widget as its parent class 73 00:04:43.339 --> 00:04:44.039 Done 74 00:04:44.799 --> 00:04:48.239 In addition, I will configure the UI first 75 00:04:50.899 --> 00:04:53.700 I will add a text block here 76 00:04:53.700 --> 00:04:57.779 for the content that goes here, text 77 00:04:57.779 --> 00:05:00.100 Then the text appears here in common 78 00:05:00.100 --> 00:05:01.259 It's a TextBlock 79 00:05:05.279 --> 00:05:07.960 Let's add this by dragging and dropping 80 00:05:10.000 --> 00:05:12.139 The text added like this 81 00:05:12.799 --> 00:05:17.599 will be uploaded here as shown on the screen 82 00:05:17.599 --> 00:05:19.319 If you look at the screen now 83 00:05:20.100 --> 00:05:22.399 the main UI looks like this 84 00:05:22.399 --> 00:05:23.899 At bottom left, right? 85 00:05:23.899 --> 00:05:27.640 Then, if you look here, the message continues to be displayed on the screen and goes up 86 00:05:28.440 --> 00:05:33.000 This message becomes a Chat message 87 00:05:33.000 --> 00:05:38.200 The server will receive the message we sent here 88 00:05:38.200 --> 00:05:42.680 Then, when it is received, the message will be added to this UI one by one like this 89 00:05:44.100 --> 00:05:44.759 Like this 90 00:05:45.799 --> 00:05:48.600 So when it is full, a scroll bar appears next to it 91 00:05:48.600 --> 00:05:49.799 like this 92 00:05:49.799 --> 00:05:56.199 So now we will create this message UI that will be displayed here 93 00:05:58.439 --> 00:06:00.559 Let's name this TextBlock 94 00:06:02.700 --> 00:06:05.979 txt_msg 95 00:06:07.399 --> 00:06:09.859 txt_msg 96 00:06:13.399 --> 00:06:16.759 Shall I add the color yellow so it stands out? 97 00:06:17.399 --> 00:06:21.379 I will process it like this to make it look darker 98 00:06:22.399 --> 00:06:24.499 and have a slightly orange tone from yellow to the eye 99 00:06:26.299 --> 00:06:30.139 I will leave the font size at around 24 100 00:06:34.519 --> 00:06:40.020 Then, the content will be entered into the text block created like this 101 00:06:41.100 --> 00:06:43.420 and the message will be displayed 102 00:06:44.139 --> 00:06:46.139 in the chat window at the bottom of the MainUI 103 00:06:47.819 --> 00:06:48.700 Done? 104 00:06:48.700 --> 00:06:55.500 Then, I will add a C++ class so that the created WBP_ChatMsg 105 00:06:55.500 --> 00:06:59.100 can inherit the C++ class 106 00:06:59.100 --> 00:07:03.100 Now, right-click on the C++ class folder 107 00:07:03.100 --> 00:07:06.720 and select New C++ class 108 00:07:09.700 --> 00:07:13.679 Find User Widgets in All Classes 109 00:07:16.099 --> 00:07:16.839 See? 110 00:07:16.839 --> 00:07:19.880 Select User Widgets and click Next 111 00:07:21.100 --> 00:07:26.820 Let's name this C++ class to be Chat Widget 112 00:07:29.899 --> 00:07:32.819 Let's click Create Class 113 00:07:36.500 --> 00:07:38.759 Now reload everything 114 00:07:41.200 --> 00:07:43.100 Go back to Unreal Editor 115 00:07:45.399 --> 00:07:52.100 ove to the UI holder, and the parent class of the Chat WBP WBP_ChatMsg 116 00:07:52.100 --> 00:07:54.339 you just created is now the User Widget 117 00:07:55.899 --> 00:07:57.799 Let's change this parent class 118 00:07:59.299 --> 00:08:03.400 Go to the graph tab and go to class settings 119 00:08:04.100 --> 00:08:08.340 In WBP_ChatMsg, go to the Graph tab 120 00:08:08.340 --> 00:08:12.799 and then the Chat Setting class settings 121 00:08:12.799 --> 00:08:16.379 If you look here, the class and Parent class are currently set to User Widgets 122 00:08:18.720 --> 00:08:24.299 Let's change this part to the ChatWidget we created 123 00:08:24.299 --> 00:08:26.200 Then ChatWidget appears like this 124 00:08:26.200 --> 00:08:29.779 Let's press this to compile it into ChatWidget 125 00:08:30.879 --> 00:08:32.159 Then, the parent class 126 00:08:33.639 --> 00:08:35.299 became ChatWidget 127 00:08:35.299 --> 00:08:38.940 Let's do this and close WBP_ChatMsg like this 128 00:08:43.239 --> 00:08:45.259 Next, it should be 129 00:08:45.259 --> 00:08:48.500 displayed in the bottom left corner of the screen 130 00:08:48.500 --> 00:08:52.000 We're going to make the chat window look like this 131 00:08:52.700 --> 00:08:56.440 We will enter a message here, create a Send button 132 00:08:56.440 --> 00:08:59.540 and process the message here to be displayed like this 133 00:08:59.540 --> 00:09:03.459 To handle this, let's open the MainUI 134 00:09:04.599 --> 00:09:06.400 There is WBP MainUI 135 00:09:06.400 --> 00:09:08.159 Let's double-click to open it 136 00:09:12.299 --> 00:09:15.320 Even GameoverUI is currently showing 137 00:09:16.400 --> 00:09:22.500 In addition, I will add a border to the bottom left 138 00:09:22.500 --> 00:09:25.459 Let's add a border from the palette 139 00:09:27.299 --> 00:09:30.939 and add it to the bottom of the canvas panel like this 140 00:09:31.639 --> 00:09:33.419 Next, as a child of the border 141 00:09:34.719 --> 00:09:36.699 what continues to be shown is 142 00:09:38.099 --> 00:09:40.500 wrapped in the border 143 00:09:40.500 --> 00:09:45.500 here will be windows where you can put messages in them, right? 144 00:09:45.500 --> 00:09:49.679 For these to fit, a scroll box needs to fit here 145 00:09:50.299 --> 00:09:54.080 Also, there needs to be an input window 146 00:09:54.099 --> 00:09:56.860 and a button below the scroll box 147 00:09:58.879 --> 00:10:02.719 so I first surround it with a Vertical Box, and in here 148 00:10:03.000 --> 00:10:08.540 let's add a scroll box, and chat messages can go in there like this 149 00:10:09.720 --> 00:10:16.360 Since this is currently a Vertical Box, we will first place a Scroll Box in this Vertical Box 150 00:10:17.518 --> 00:10:19.358 then a Horizontal Box here 151 00:10:20.678 --> 00:10:21.978 and we will process the input back 152 00:10:23.240 --> 00:10:26.780 into the Horizontal Box and then a button 153 00:10:28.840 --> 00:10:31.180 Now, let's try making it with this structure 154 00:10:33.719 --> 00:10:36.640 Add a Vertical Box under the border 155 00:10:38.480 --> 00:10:42.599 Let's search and register the Vertical Box as a child of the border 156 00:10:44.878 --> 00:10:49.158 Next, I'm going to add a scroll box 157 00:10:50.600 --> 00:10:54.700 Let's grab the scroll box and place it as a child of the Vertical Box 158 00:10:58.238 --> 00:11:04.458 Next, let's grab the Horizontal box, which will be responsible for the input window and send button 159 00:11:04.458 --> 00:11:09.240 and place it as a child of the Vertical Box 160 00:11:13.440 --> 00:11:15.280 Inside this 161 00:11:16.058 --> 00:11:18.558 we will put an input window and a send button 162 00:11:21.239 --> 00:11:26.959 If you simply input here, the back will become too transparent 163 00:11:26.959 --> 00:11:34.440 so you will simply input text in the transparent area, and let's add another border here 164 00:11:34.440 --> 00:11:39.080 We will add a border to the Horizontal Box and use this border 165 00:11:39.080 --> 00:11:41.518 as a child of the border 166 00:11:42.120 --> 00:11:44.020 As a child of the border 167 00:11:46.360 --> 00:11:48.939 I'll add Editable Text 168 00:11:51.879 --> 00:11:56.540 Let's grab the Editable Text as a child of the border and insert it into it 169 00:11:58.818 --> 00:12:04.298 Then, we need to create a send button 170 00:12:04.298 --> 00:12:09.280 Add a button to the Send button and add it as a child to this Horizontal Box 171 00:12:09.280 --> 00:12:13.000 Now, there is Editable Text on the border 172 00:12:13.001 --> 00:12:17.460 There is a button like this at the same level as the border 173 00:12:17.460 --> 00:12:22.199 Now, we grab the text that will give the name to this button and call it TextBlock 174 00:12:22.199 --> 00:12:25.999 Let's grab it and put it as a child in the button like this 175 00:12:27.759 --> 00:12:33.359 Now, what has been added is a Vertical Box under the border, then a Scroll Box 176 00:12:34.039 --> 00:12:38.200 and then a Horizontal Box with a border button 177 00:12:39.018 --> 00:12:40.378 under the Horizontal Box 178 00:12:44.000 --> 00:12:45.520 Set it like this 179 00:12:47.440 --> 00:12:51.380 Let me add some names I'll enter the names of the widgets like this 180 00:12:54.720 --> 00:13:01.380 Now, there is a scroll box here, and I'll name it scroll_msgList 181 00:13:05.220 --> 00:13:11.679 I named it this way because the message is now registered in this scroll box 182 00:13:12.978 --> 00:13:17.078 Now, there is Editable Text below the border 183 00:13:17.078 --> 00:13:23.759 Let's add edit_input to receive text input from the user 184 00:13:26.379 --> 00:13:32.479 Next, there is a button, and I'll name it btn_send 185 00:13:35.479 --> 00:13:39.880 Then, let me lay out their layout 186 00:13:40.880 --> 00:13:45.800 Now, first, select the border 187 00:13:47.600 --> 00:13:52.539 So, I will make sure it's positioned at the bottom left here like this 188 00:13:54.320 --> 00:14:01.119 so it's sorted based on this 189 00:14:02.759 --> 00:14:06.438 So I'm going to open this anchor dropdown in the anchor preset 190 00:14:06.438 --> 00:14:09.798 and then select the bottom left bottom 191 00:14:12.639 --> 00:14:16.879 I put position X and Y as 0, 0 192 00:14:20.980 --> 00:14:25.979 and then there's the alignment I'll just raise this 193 00:14:27.938 --> 00:14:32.918 We will catch it to this extent, grow it, and then catch it and put it in this amount 194 00:14:32.919 --> 00:14:36.080 Border size, so that the border is on this side like this 195 00:14:37.799 --> 00:14:43.860 If it turns white like this, what happens when you play? 196 00:14:44.478 --> 00:14:47.218 It blocks the screen, so it doesn't look good 197 00:14:47.218 --> 00:14:51.480 So, let me change the color of this border so that it is transparent 198 00:14:53.640 --> 00:14:56.659 Now, if you come to the right and look at the brush 199 00:14:56.659 --> 00:14:59.338 you can see that you can insert an image here 200 00:15:00.839 --> 00:15:02.279 and there is also a brush color 201 00:15:04.018 --> 00:15:08.238 Where? When you come to this border, there is a brush color under the brush 202 00:15:08.240 --> 00:15:11.839 Now, let's select the brush color and reduce the alpha value like this 203 00:15:11.839 --> 00:15:14.300 Then, when you look at it from behind, the transparency changes 204 00:15:16.119 --> 00:15:21.980 I'll make only about 30% transparent like this and click ok 205 00:15:25.079 --> 00:15:27.479 If you click compile and check 206 00:15:28.038 --> 00:15:31.518 it will be displayed transparently like this 207 00:15:36.119 --> 00:15:36.940 It's done 208 00:15:39.200 --> 00:15:45.340 Next, we have scroll_msgList scroll box 209 00:15:47.040 --> 00:15:48.159 select this 210 00:15:50.040 --> 00:15:53.640 Let's go to the details window on the right 211 00:15:54.800 --> 00:15:56.079 and change the size to Fill 212 00:15:58.418 --> 00:16:00.018 If you change the size to Fill 213 00:16:00.698 --> 00:16:06.079 the scroll msgList takes up almost the entire screen 214 00:16:08.858 --> 00:16:10.958 Then, because it goes too far, it becomes like this 215 00:16:10.958 --> 00:16:13.639 Since we can work with these as percentages 216 00:16:14.979 --> 00:16:19.399 let's put Fill here as 4.0 217 00:16:23.320 --> 00:16:27.820 Then we'll press Horizontal Box 218 00:16:27.820 --> 00:16:32.660 When it is 1 and when it is 4, it has a size 219 00:16:35.558 --> 00:16:37.378 Then, I will click the Horizontal Box and change this to Fill 220 00:16:37.378 --> 00:16:41.100 Let's change the size to Fill in the details window on the right 221 00:16:44.958 --> 00:16:48.140 I processed it like this to make it look roughly bigger 222 00:16:48.140 --> 00:16:52.519 You can adjust it according to the layout you want 223 00:16:52.519 --> 00:16:55.300 First, I set it to Fill and set it like this 224 00:16:58.138 --> 00:17:00.798 I'll do it like this, and then 225 00:17:02.357 --> 00:17:03.457 I'll leave the border 226 00:17:04.239 --> 00:17:06.480 as Fill 227 00:17:07.600 --> 00:17:11.300 If you look below, you will see a border under the Horizontal Box 228 00:17:11.301 --> 00:17:15.517 Let's set this Border to Fill and leave it at 1.0 for now 229 00:17:16.440 --> 00:17:20.499 Then there is the Edit Input below 230 00:17:23.799 --> 00:17:31.920 I put the Edit Input like this, and the border color is too dark, so it doesn't look transparent like this 231 00:17:31.921 --> 00:17:35.060 If you look at it now, the screen is covered like this 232 00:17:35.060 --> 00:17:39.640 So, let me change the color of this border 233 00:17:39.640 --> 00:17:44.739 If you go to the right, you can see the brush color 234 00:17:44.740 --> 00:17:49.117 Let's roughly make it stand out from the Brush Color and make it a little more pink 235 00:17:49.117 --> 00:17:51.739 Let's reduce the alpha value like this 236 00:17:53.559 --> 00:17:59.100 If you set only about 30% like this and compile it 237 00:17:59.101 --> 00:18:04.140 it is divided like this when you go to see it to enter the text 238 00:18:04.160 --> 00:18:05.979 It goes like this 239 00:18:08.000 --> 00:18:14.920 Then, in the Edit Input, enter the first message 240 00:18:14.920 --> 00:18:19.920 I will add this to the Hint Text so that it appears 241 00:18:19.920 --> 00:18:24.657 We will insert it like this: Insert MSG 242 00:18:24.657 --> 00:18:27.317 Then, if you look here, it says Insert MSG 243 00:18:30.079 --> 00:18:33.119 If you want to align it in the exact center 244 00:18:33.119 --> 00:18:37.697 you can do it so that the phone text is in the exact center in Justification 245 00:18:37.697 --> 00:18:41.490 and then in Vertical, it is at the bottom like this 246 00:18:44.777 --> 00:18:47.477 Set it right in the center for Vertical Alignment 247 00:18:47.477 --> 00:18:51.919 If you do this in Justification, it will be centered 248 00:18:51.919 --> 00:18:56.919 I want to type from the far left, so it will be filled in by typing from the left 249 00:18:59.119 --> 00:19:05.109 In the Vertical Alignment, we will leave Justification on the far left 250 00:19:06.159 --> 00:19:10.489 We can also input the font color here 251 00:19:14.520 --> 00:19:19.020 Here, there is Color & Opacity and the color at the border 252 00:19:20.320 --> 00:19:27.479 As you can see, if you click on Color & Opacity, it changes to black, which lowers the color 253 00:19:27.479 --> 00:19:31.340 The hint says to enter a message like this 254 00:19:34.520 --> 00:19:36.050 You can see it coming out 255 00:19:39.280 --> 00:19:43.689 Here, Color & Opacity appears in Input 256 00:19:45.559 --> 00:19:51.440 I'll compile it and go and play it Then, an Insert message appears here 257 00:19:51.440 --> 00:19:55.939 Now, I'll enter 'Hello' 258 00:19:55.957 --> 00:19:59.357 The hint message disappears, and the message we entered appears 259 00:19:59.359 --> 00:20:04.049 At this time, if you click the button next to it, it will be transmitted 260 00:20:04.049 --> 00:20:07.137 Let's go back to WBP_MainUI 261 00:20:08.597 --> 00:20:11.377 press btn_send 262 00:20:12.717 --> 00:20:16.837 btn_send is currently full 263 00:20:19.637 --> 00:20:25.337 So, the border is currently set to 1, so the message window can widen 264 00:20:25.338 --> 00:20:27.977 btn_send is now set to auto 265 00:20:27.997 --> 00:20:29.537 so change it to Fill 266 00:20:30.597 --> 00:20:31.877 I'll change it to Fill 267 00:20:32.897 --> 00:20:35.777 and leave the skill value behind as 1.0 268 00:20:35.778 --> 00:20:40.257 So that the border value above takes up more space 269 00:20:40.257 --> 00:20:43.677 I will change the Fill part to 1.0 and change it to 3.0 270 00:20:43.677 --> 00:20:49.057 Then there is an insert message and a text box is added next to it like this 271 00:20:49.057 --> 00:20:55.497 Let's change the name of this text box, and name the text box's name under btn_send 272 00:20:55.498 --> 00:20:58.337 Send 273 00:20:58.337 --> 00:20:59.676 So that the message is sent 274 00:21:01.215 --> 00:21:03.735 Right? Should we change the color to black? 275 00:21:04.956 --> 00:21:05.616 Like this 276 00:21:07.717 --> 00:21:13.877 So, the text is too slanted to one side so that the user can enter 277 00:21:13.877 --> 00:21:16.926 the message by pressing the send button 278 00:21:17.977 --> 00:21:21.797 In this Justification, we will change it to center alignment 279 00:21:23.636 --> 00:21:28.227 There is a TextBlock under btn_send 280 00:21:29.517 --> 00:21:34.996 I named it Send, and then, if you scroll down, there is Justification 281 00:21:34.996 --> 00:21:38.376 I placed it like this so that Justification is centered 282 00:21:39.877 --> 00:21:43.076 Let's put it like this, click compile, and then go and take a look 283 00:21:43.076 --> 00:21:46.796 When you press the play button, it is placed at the bottom left like this 284 00:21:46.796 --> 00:21:51.677 Since the bullet and the UI overlap a little now 285 00:21:51.678 --> 00:21:56.007 I will grab this border that overlaps the bullet and raise it to the top 286 00:21:57.676 --> 00:22:02.276 If you click compile and go back, it looks like this 287 00:22:02.277 --> 00:22:06.296 Here, you type hello 288 00:22:06.296 --> 00:22:10.436 Then, when you press the send button, we will send it 289 00:22:10.436 --> 00:22:15.747 So far, I've created a Chat UI 290 00:22:16.371 --> 00:22:19.191 Implement Chat Logic 291 00:22:20.416 --> 00:22:22.306 The chat logic implementation 292 00:22:24.037 --> 00:22:29.096 will be implemented in the same way as the RPG communication described above 293 00:22:34.157 --> 00:22:36.157 First, in the client 294 00:22:37.957 --> 00:22:41.816 the user will enter a chat message 295 00:22:43.876 --> 00:22:48.226 This chat message is then transmitted to the server 296 00:22:50.677 --> 00:22:55.546 Then this server receives the message 297 00:22:55.546 --> 00:22:58.177 Once sent, the server receives the message 298 00:22:59.916 --> 00:23:04.377 We will receive it, simply process it 299 00:23:04.378 --> 00:23:07.017 here as a server 300 00:23:07.017 --> 00:23:09.737 and broadcast the message to all clients 301 00:23:10.916 --> 00:23:14.617 This means transmitting, so we will use NetMulticast 302 00:23:18.076 --> 00:23:22.847 to transmit it from the server to the client again 303 00:23:26.896 --> 00:23:30.837 Then, each client receives this message 304 00:23:30.838 --> 00:23:32.477 and visualizes it on the screen 305 00:23:32.477 --> 00:23:34.446 It is displayed on the UI 306 00:23:36.817 --> 00:23:37.817 We will receive this content 307 00:23:40.036 --> 00:23:44.117 and process it like this For this, we will implement Server RPC 308 00:23:44.117 --> 00:23:46.977 and NetMulticast with this content 309 00:23:48.117 --> 00:23:54.617 First, we have these UIs in the WBP main we created earlier 310 00:23:55.397 --> 00:23:57.177 Let's move on to Visual Studio to use these UI widgets 311 00:23:59.276 --> 00:24:03.276 In Visual Studio, move to the header file of the main UI 312 00:24:03.277 --> 00:24:05.436 Let's move the bottom part 313 00:24:05.436 --> 00:24:10.117 Now, let me add chat-related content here 314 00:24:14.477 --> 00:24:16.177 public 315 00:24:20.357 --> 00:24:26.157 Put UPROPERTY below this, edit defaults only 316 00:24:26.157 --> 00:24:29.297 Then TsubclassOf 317 00:24:30.836 --> 00:24:32.036 Class 318 00:24:32.036 --> 00:24:36.876 This message will be added to this chat window I will put the received message here 319 00:24:36.877 --> 00:24:42.236 Enter the UChatWidget type class for the message to be received 320 00:24:42.237 --> 00:24:44.496 Let's put it as a chatWidget 321 00:24:44.496 --> 00:24:49.317 We created this chat widget here 322 00:24:49.318 --> 00:24:52.617 Now, if you look, there was a WBP chatmsg 323 00:24:52.617 --> 00:24:57.457 The parent class that WBP chatmsg inherits from is chatWidget 324 00:24:59.317 --> 00:25:05.117 We're trying to take that widget and continue adding it to the scroll box 325 00:25:06.836 --> 00:25:11.517 Next, let's add the widgets we want to add here as members 326 00:25:12.357 --> 00:25:19.157 This time, add blueprint_read_write to UPROPERTY 327 00:25:19.157 --> 00:25:25.477 Let's bind it using the meta keyword BindWidget 328 00:25:25.477 --> 00:25:32.316 Add the class UScrollBox widget here 329 00:25:32.316 --> 00:25:33.096 The name 330 00:25:35.276 --> 00:25:36.276 of the variable was 331 00:25:37.817 --> 00:25:42.996 scroll_msgList in the MainUI 332 00:25:42.996 --> 00:25:45.957 So I'll take it as is and put it in like this 333 00:25:47.797 --> 00:25:52.936 Copy UPROPERTY above and add another one 334 00:25:53.496 --> 00:25:58.316 and add class UEditableText 335 00:26:01.556 --> 00:26:06.817 I put it as edit_input Let me add one more 336 00:26:09.077 --> 00:26:13.917 Here, class UButton, I'll connect it with send button 337 00:26:13.917 --> 00:26:17.437 Let's put btn_send like this 338 00:26:19.477 --> 00:26:25.357 By using bind widgets like this, you match the widgets' names as they are 339 00:26:25.358 --> 00:26:27.397 The names must be the same 340 00:26:27.397 --> 00:26:30.336 Only then can they all be uploaded to this BindWidget 341 00:26:34.456 --> 00:26:37.997 Let's do this and add a function 342 00:26:37.997 --> 00:26:41.637 that will send a message when the btn_send button is clicked 343 00:26:41.637 --> 00:26:47.877 Let's put UFunction void SendMsg 344 00:26:47.877 --> 00:26:54.157 SendMsg When this function is called, let's process it so that a message is sent here 345 00:26:54.158 --> 00:26:55.837 I think I need to get it, too 346 00:26:55.838 --> 00:26:59.517 Let's enter void ReceiveMsg 347 00:26:59.517 --> 00:27:05.417 and enter the received message as const FString msg 348 00:27:07.357 --> 00:27:10.016 Now, we have added the two functions we need here 349 00:27:12.036 --> 00:27:16.877 Implement sendmsg in mainui.cpp 350 00:27:18.197 --> 00:27:22.036 It came out like this Then, I will add receive msg as well 351 00:27:22.756 --> 00:27:24.076 These two 352 00:27:28.256 --> 00:27:31.596 SendMsg will process like this so that 353 00:27:31.596 --> 00:27:35.356 this SendMsg is executed when btn_send is pressed 354 00:27:37.016 --> 00:27:39.197 So, if we look at the native construct 355 00:27:40.157 --> 00:27:43.717 we will add it under btn_retry like this 356 00:27:46.116 --> 00:27:50.746 Let's do btn_send here 357 00:27:50.816 --> 00:27:52.476 then 358 00:27:53.976 --> 00:27:56.476 SendMsg and connect like this 359 00:27:58.276 --> 00:28:00.536 Then, we will process it like this 360 00:28:00.536 --> 00:28:03.337 so that the sendmsg function is called when btn_send is clicked 361 00:28:08.276 --> 00:28:13.877 So what do you do when this sendmsg is called 362 00:28:13.877 --> 00:28:18.397 It will ask you to send it to the server 363 00:28:18.397 --> 00:28:24.476 When the client receives input like this, it will be sent to the server in the SendMsg function 364 00:28:24.476 --> 00:28:28.097 How? With Server RPC 365 00:28:30.196 --> 00:28:33.177 We will send it using Server RPC 366 00:28:36.416 --> 00:28:40.196 Then, the server will receive this Server RPC request 367 00:28:40.196 --> 00:28:45.277 and send a message to all clients using NetMulticast 368 00:28:50.116 --> 00:28:53.976 You can put this in several classes 369 00:28:53.976 --> 00:28:57.997 You can put it in NetPlayerController 370 00:28:57.998 --> 00:29:00.977 and then you can put this part in the net_tps character 371 00:29:00.977 --> 00:29:03.716 Or you can bring it in through other actors 372 00:29:03.717 --> 00:29:06.956 However, we explained in our communication connection structure 373 00:29:06.956 --> 00:29:10.917 that for communication to occur 374 00:29:10.917 --> 00:29:16.496 this client must have someone as a result 375 00:29:16.496 --> 00:29:18.916 You must have a PlayerController 376 00:29:19.876 --> 00:29:22.817 This PlayerController 377 00:29:22.818 --> 00:29:26.557 has the net_connection and needs to communicate through 378 00:29:26.557 --> 00:29:30.856 So the type that can have this PlayerController is 379 00:29:30.856 --> 00:29:32.876 called the owner 380 00:29:35.037 --> 00:29:39.587 That's right, it's a structure that allows communication through this owner 381 00:29:39.588 --> 00:29:42.747 and ultimately through the net_connection object in PlayerController 382 00:29:42.747 --> 00:29:45.036 So, the form that can be had like this is, first 383 00:29:45.037 --> 00:29:48.396 the PlayerController is a Pawn that Possesses a client, right? 384 00:29:50.316 --> 00:29:52.896 If we use our character here 385 00:29:52.897 --> 00:29:55.876 we will have a PlayerController to communicate 386 00:29:55.876 --> 00:29:59.617 Next, create an actor to communicate with a general actor 387 00:29:59.618 --> 00:30:03.516 and set the owner for this communication actor 388 00:30:05.315 --> 00:30:10.255 You use a pawn or PlayerController to set the owner 389 00:30:11.955 --> 00:30:15.116 Then, you can use this actor to chat 390 00:30:15.116 --> 00:30:17.696 through the connection in the PlayerController 391 00:30:18.755 --> 00:30:22.276 You have to handle it this way for chatting 392 00:30:22.276 --> 00:30:26.096 or do these chat content to 393 00:30:27.075 --> 00:30:30.894 PlayerController 394 00:30:31.716 --> 00:30:34.936 If you send a Server RPC to the PlayerController 395 00:30:34.954 --> 00:30:38.836 the PlayerController can just take the Server RPC 396 00:30:38.836 --> 00:30:41.055 and send it to the server itself 397 00:30:42.355 --> 00:30:46.915 But when it happens like this, there are things we need to consider 398 00:30:48.954 --> 00:30:51.454 There is a server, and there is a client 399 00:30:55.074 --> 00:31:00.374 They all have their own PlayerController 400 00:31:00.375 --> 00:31:04.114 How about a server? I have all the PlayerControllers 401 00:31:04.114 --> 00:31:07.754 and matching PlayerControllers for the server now 402 00:31:09.275 --> 00:31:13.735 So, P0 communicates with P0 403 00:31:13.735 --> 00:31:15.815 and P1 communicates with P1 in this structure 404 00:31:15.815 --> 00:31:17.555 That's because the server has them all 405 00:31:18.955 --> 00:31:21.595 Now, what kind of problem arises here? 406 00:31:21.595 --> 00:31:26.395 Look, this problem occurs when sending a message 407 00:31:26.396 --> 00:31:29.075 from the server to the client First, the client makes a request to the server 408 00:31:29.075 --> 00:31:34.234 using Server RPC 409 00:31:34.255 --> 00:31:37.715 Then, let's look at NetMulticast from this server's perspective 410 00:31:37.715 --> 00:31:44.315 But what problems will arise if NetMulticast is implemented in PlayerController? 411 00:31:45.375 --> 00:31:51.594 When it's sent, then, from the server's point of view, I want to send it through NetMulticast 412 00:31:51.594 --> 00:31:57.074 but all clients must have the ones corresponding to this P0 413 00:31:57.075 --> 00:32:01.055 to communicate through the PlayerController 414 00:32:01.895 --> 00:32:02.895 But there isn't one 415 00:32:04.074 --> 00:32:08.635 So, you can't use NetMulticast if you use PlayerController 416 00:32:09.995 --> 00:32:13.995 On the other hand, if you just use regular Client RPC 417 00:32:15.775 --> 00:32:19.675 when you use this Client RPC, you can do this 418 00:32:20.294 --> 00:32:25.815 It is sent from the client to the server through this PlayerController 419 00:32:25.815 --> 00:32:32.115 And server sends a message to each of them 420 00:32:32.115 --> 00:32:38.375 Now, P0 is sent to P0 The server sends P0 to P0 421 00:32:38.376 --> 00:32:43.255 Then, P1 sends it to P1; since it is a client, it is sent only to each client 422 00:32:44.135 --> 00:32:46.895 Then send P2 to P2, and what if it goes like this? 423 00:32:46.895 --> 00:32:51.535 Communication is possible because all clients have their communication structure 424 00:32:52.035 --> 00:32:54.714 But what happens if you use NetMulticast? 425 00:32:57.954 --> 00:33:04.415 Since the PlayerController only has its right now, when the server sends it 426 00:33:05.195 --> 00:33:10.234 if you NetMulticast it, you can receive the one corresponding to this P0 427 00:33:10.234 --> 00:33:15.095 NetMulticast But since there is no P0 here, there are no actors 428 00:33:15.915 --> 00:33:18.315 You can't send data to an actor that doesn't exist 429 00:33:18.315 --> 00:33:20.855 So, for actor replication to occur 430 00:33:21.175 --> 00:33:25.555 the actor must be in the same world space, but communication itself is impossible because it is not there 431 00:33:26.675 --> 00:33:30.555 So, if you try to use NetMulticast with this PlayerController 432 00:33:30.556 --> 00:33:33.475 a problem will arise 433 00:33:33.475 --> 00:33:38.294 At this time, if you try to display the message to all clients using PlayerController 434 00:33:38.295 --> 00:33:42.915 the message will be sent using Client RPC, not NetMulticast RPC 435 00:33:42.916 --> 00:33:46.535 Then, we use this technique of going around the for loop 436 00:33:46.535 --> 00:33:49.494 and sending Client RPCs to all PlayerControllers individually 437 00:33:51.594 --> 00:33:56.714 So what we're going to choose now is that part seems too complicated 438 00:33:56.714 --> 00:33:59.635 Instead of implementing it in PlayerController 439 00:33:59.635 --> 00:34:02.235 we will put this content in the NetTPS character 440 00:34:02.995 --> 00:34:05.895 So what about this character? 441 00:34:07.055 --> 00:34:11.155 It's in every world right now 442 00:34:11.156 --> 00:34:13.315 There is also C1 here 443 00:34:13.316 --> 00:34:17.315 Here too, C1, C2, and C1 are together 444 00:34:17.316 --> 00:34:21.215 If you look at the window, this is the window 445 00:34:21.215 --> 00:34:25.116 If you look at the C1 character's window, you can see C1 player 446 00:34:25.116 --> 00:34:28.035 C2 player, and C3 player on the screen 447 00:34:29.235 --> 00:34:33.735 Likewise, in the C2 window, you will see your own C2 character 448 00:34:33.735 --> 00:34:40.655 and the C1, C0, and C3 characters 449 00:34:40.655 --> 00:34:47.475 In the c3 window, these actors also exist together, so NetMulticast RPC can be used now 450 00:34:48.674 --> 00:34:55.075 On the other hand, there is only PlayerController corresponding to P0 451 00:34:55.075 --> 00:34:57.695 So, if you send a message using the PlayerController actor 452 00:34:57.696 --> 00:35:00.995 and you try to use NetMulticast 453 00:35:00.995 --> 00:35:05.035 communication is impossible because there is no P0 here 454 00:35:08.154 --> 00:35:11.955 So, to simply use this NetMulticast 455 00:35:11.956 --> 00:35:14.455 let's move to the NetTPS character header file 456 00:35:14.455 --> 00:35:20.555 I'll put the public at the bottom, and I'll put the chat content here 457 00:35:23.395 --> 00:35:26.755 Now, let's add a Server RPC function here 458 00:35:26.755 --> 00:35:29.335 UFUNCTION server 459 00:35:32.115 --> 00:35:35.635 and then Reliable 460 00:35:35.635 --> 00:35:37.835 void ServerRPC 461 00:35:39.835 --> 00:35:44.755 _SendMsg 462 00:35:44.755 --> 00:35:51.395 Set the const message to be sent as FString msg 463 00:35:53.755 --> 00:35:58.555 Similarly, NetMulticast is now required for reception 464 00:35:58.555 --> 00:36:03.895 So this is not a server, but NetMulticast 465 00:36:03.895 --> 00:36:08.755 Set it to void MultiRPC 466 00:36:08.755 --> 00:36:11.755 Let's set up MulticastRPC like this 467 00:36:11.755 --> 00:36:15.755 Please enter the name in a format that you can identify 468 00:36:16.595 --> 00:36:23.435 In addition, send msg will be the message to be displayed on the received message screen 469 00:36:23.435 --> 00:36:27.675 Let's put const FString msg like this 470 00:36:31.915 --> 00:36:37.755 Let's try to implement this part, which can be sent through Server RPC 471 00:36:37.755 --> 00:36:42.235 Next, we will also add Multicast RPC 472 00:36:45.235 --> 00:36:50.775 Then, these two functions were added to the NetTPSCharter cpp file 473 00:36:54.495 --> 00:36:59.995 The server is simple; it just receives messages from clients 474 00:36:59.995 --> 00:37:04.755 It will simply receive the message from the client and transmit it via multicast 475 00:37:04.755 --> 00:37:05.915 It only acts as a relay 476 00:37:07.555 --> 00:37:11.755 Server RPC simply acts as a relay to transmit messages 477 00:37:11.755 --> 00:37:15.365 Here, the Multicast RPC 478 00:37:15.365 --> 00:37:20.335 SengMsg call is made like this Simply send the message you received her 479 00:37:24.335 --> 00:37:30.075 So, where is this multicast part being performed now? 480 00:37:30.075 --> 00:37:36.035 Client, and where is this? Literally, server 481 00:37:37.555 --> 00:37:42.135 When you press the send msg button on the client, Server RPC is executed 482 00:37:42.135 --> 00:37:45.503 and its function is simply to send 483 00:37:45.503 --> 00:37:47.563 messages to all clients 484 00:37:48.155 --> 00:37:51.494 Now, send msg to Server RPC 485 00:37:51.494 --> 00:37:55.114 SendMsg Let's implement the part that calls this 486 00:37:58.215 --> 00:38:00.695 Move to MainUI cpp 487 00:38:01.734 --> 00:38:04.074 Let's go to SendMsg 488 00:38:05.215 --> 00:38:14.635 Here, we want to implement the idea of transmitting the message entered by the user to the server 489 00:38:17.395 --> 00:38:22.055 Then, the message entered by the user must be received and memorized 490 00:38:25.135 --> 00:38:30.705 We will receive this entered message as fstring and put it as msg 491 00:38:30.705 --> 00:38:36.735 This can be retrieved from the widget through the edit input widget 492 00:38:36.755 --> 00:38:44.905 Let's get it here with get text and convert it to string 493 00:38:47.115 --> 00:38:53.515 This takes the message from the editable text and puts it into the FString 494 00:38:56.535 --> 00:38:58.385 Next 495 00:38:59.375 --> 00:39:03.034 We put in here, the user pressed the send button 496 00:39:03.034 --> 00:39:06.684 Then, in the message window sent from the UI 497 00:39:06.814 --> 00:39:09.194 This input field editable text 498 00:39:10.755 --> 00:39:15.835 would be better to delete the data and make it blank 499 00:39:16.554 --> 00:39:21.794 So here, in the set text of the edit input 500 00:39:23.015 --> 00:39:31.755 we will insert a blank character from the GETEmpty of the FTect, which has nothing 501 00:39:31.755 --> 00:39:32.914 Next 502 00:39:34.915 --> 00:39:38.235 if there is data in this msg 503 00:39:38.235 --> 00:39:43.814 if you press send when it is blank, sending it to the server for no reason will result in a waste of data packing, right? 504 00:39:43.814 --> 00:39:54.295 Send to the server only if there is a message to send in msg 505 00:39:55.495 --> 00:40:00.035 if msg has IsEmpty 506 00:40:03.114 --> 00:40:06.234 This means sending when this value is false 507 00:40:07.674 --> 00:40:08.734 So here's 508 00:40:10.514 --> 00:40:14.254 the character I'm sending here 509 00:40:14.254 --> 00:40:18.754 I'm trying to call Server RPC on this NetTPSCharacter 510 00:40:19.554 --> 00:40:21.813 Right? In this MainUI 511 00:40:21.813 --> 00:40:26.074 if you want to get a pawn that has itself in the MainUI 512 00:40:26.074 --> 00:40:29.034 you can use it like this 513 00:40:29.034 --> 00:40:33.154 In this case, we just spread the MainUI 514 00:40:33.154 --> 00:40:35.034 around the world 515 00:40:35.034 --> 00:40:36.634 This is the thing that spreads out like that 516 00:40:36.634 --> 00:40:39.054 So how can this MainUI 517 00:40:39.054 --> 00:40:41.874 get NetTPSCharacter? 518 00:40:43.534 --> 00:40:46.513 From PlayerController 519 00:40:47.393 --> 00:40:50.713 if we get the Pawn that PlayerController is currently Possessing 520 00:40:50.713 --> 00:40:53.753 it will be this NetTPSCharacter 521 00:40:53.753 --> 00:40:57.073 We can use the ServerRPC on that character 522 00:40:57.073 --> 00:41:00.114 so we need a PlayerController first 523 00:41:06.653 --> 00:41:13.154 So, import Cast NetPlayerController from auto pc 524 00:41:13.154 --> 00:41:16.154 In get world 525 00:41:19.353 --> 00:41:23.753 If we get GetFirstPlayerController here 526 00:41:23.753 --> 00:41:26.193 we can get PlayerController 527 00:41:28.713 --> 00:41:31.603 Then, from this PlayerController 528 00:41:31.603 --> 00:41:35.834 we can retrieve the character currently being used as Possess 529 00:41:35.834 --> 00:41:38.353 Set it to the auto-player 530 00:41:38.353 --> 00:41:41.614 Cast ANetTPSCharacter 531 00:41:43.734 --> 00:41:45.384 Who do you get it from? 532 00:41:45.384 --> 00:41:50.873 You can get it by using GetPawn from the PlayerController 533 00:41:54.033 --> 00:41:55.514 Then, this PlayerController 534 00:41:55.514 --> 00:41:59.114 takes the currently Possessed Pawn 535 00:41:59.114 --> 00:42:01.793 and casts it to the ANetTPSCharacter type 536 00:42:02.653 --> 00:42:07.114 Then, this player will contain that instance 537 00:42:07.114 --> 00:42:11.594 So we can call ServerRPC on this player 538 00:42:12.494 --> 00:42:17.733 Send message, we can put the message we sent here like this 539 00:42:21.393 --> 00:42:23.673 Then, when the user presses the send button 540 00:42:23.673 --> 00:42:25.593 the message is retrieved 541 00:42:25.593 --> 00:42:28.074 and stored in 542 00:42:28.074 --> 00:42:32.313 the editable input window 543 00:42:32.313 --> 00:42:35.074 and then the contents of the Editable Text are deleted 544 00:42:35.074 --> 00:42:36.714 Leave it blank 545 00:42:36.714 --> 00:42:38.633 and then, if there is a message to send 546 00:42:38.634 --> 00:42:40.613 import PlayerController 547 00:42:40.613 --> 00:42:45.374 and ANetTPSCharacter, which is the Pawn it is Possessing 548 00:42:46.394 --> 00:42:49.233 Then we can call the ServerRPC send message 549 00:42:49.233 --> 00:42:51.914 in the ANetTPSCharacter we created 550 00:42:51.914 --> 00:42:54.273 Then, this is the structure where it is transmitted directly to the server 551 00:42:56.833 --> 00:43:01.834 Looking at it now, it looks like Editable Text should be added to the header 552 00:43:02.774 --> 00:43:05.373 So #include here 553 00:43:08.313 --> 00:43:11.194 Let's add component dot component slash 554 00:43:11.194 --> 00:43:15.033 EditableText.h here like this 555 00:43:18.393 --> 00:43:21.593 Next, we need to be able to use NetTPSCharacter as well 556 00:43:21.593 --> 00:43:25.634 Then #include 557 00:43:25.634 --> 00:43:29.613 Let's add NetTPSCharacter.h like this 558 00:43:32.033 --> 00:43:37.473 Then, I implemented the content to be used in the send message 559 00:43:39.953 --> 00:43:41.493 Build 560 00:43:44.233 --> 00:43:46.513 Okay, then the receive message 561 00:43:46.513 --> 00:43:51.393 the user sent a message to the sub 562 00:43:52.473 --> 00:43:59.074 Then, NetTPSCharacter simply sends messages like this to users 563 00:44:00.793 --> 00:44:05.153 Then, users will receive this multicast RPC send message 564 00:44:07.793 --> 00:44:11.153 So what are you going to do here? 565 00:44:11.153 --> 00:44:14.913 We are the client, so we must get the MainUI from here 566 00:44:17.593 --> 00:44:19.433 And you will need to call 567 00:44:21.613 --> 00:44:23.474 the receive function in this MainUI 568 00:44:27.834 --> 00:44:31.133 That way, you can print the message on the screen 569 00:44:33.554 --> 00:44:38.114 I think you need to know a little more about this in detail now 570 00:44:42.594 --> 00:44:48.513 On the screen, we are trying to send a NetMulticast RPC call 571 00:44:48.513 --> 00:44:52.673 Then, there is a screen like this This is C1 character 572 00:44:52.673 --> 00:44:56.073 The C1 character looks like this 573 00:44:56.073 --> 00:44:57.533 For this one, I will set 574 00:44:59.033 --> 00:45:00.293 the PlayerController as P0 575 00:45:01.673 --> 00:45:07.114 Then there is the C2 character and then the C3 character 576 00:45:07.114 --> 00:45:09.874 Do they currently have a PlayerController or not? 577 00:45:09.874 --> 00:45:14.493 Similarly, this time we come here 578 00:45:15.874 --> 00:45:19.453 this is now 579 00:45:19.453 --> 00:45:23.994 a C2 character 580 00:45:23.994 --> 00:45:27.473 This time, it has its own PlayerController 581 00:45:27.473 --> 00:45:30.194 Next, this is a C1 character 582 00:45:32.034 --> 00:45:35.314 Since there are too many, I will remove C3 583 00:45:35.314 --> 00:45:38.893 So there are two players, right? 584 00:45:39.674 --> 00:45:44.274 Now, they want to send these messages to the server 585 00:45:47.594 --> 00:45:51.773 If they want to send the message to the server 586 00:45:53.073 --> 00:45:56.793 In the send message 587 00:45:56.793 --> 00:45:59.473 you are currently sending a message to the server through this Pawn 588 00:46:02.493 --> 00:46:05.513 It's sending it 589 00:46:05.513 --> 00:46:08.953 In this case, the server will multicast again 590 00:46:09.814 --> 00:46:12.753 and send it to this Shall we try using a different color? 591 00:46:12.753 --> 00:46:16.173 I will send it to him like this 592 00:46:16.793 --> 00:46:18.394 and then this one here is C1, right? 593 00:46:18.413 --> 00:46:21.573 I'm going to send it to this guy right now 594 00:46:22.073 --> 00:46:24.393 So, NetMulticast is completed 595 00:46:25.653 --> 00:46:27.613 Right? Then 596 00:46:27.613 --> 00:46:31.834 what about this case where the main character is yourself? 597 00:46:32.734 --> 00:46:35.853 Well, it doesn't matter 598 00:46:35.854 --> 00:46:37.953 It has a PlayerController 599 00:46:37.953 --> 00:46:40.273 and a MainUI on its own 600 00:46:41.373 --> 00:46:44.413 If the MainUI is currently in a PlayerController 601 00:46:44.413 --> 00:46:46.893 the MainUI is active on itself 602 00:46:48.034 --> 00:46:51.414 But let's see when it sends a message to C2 character 603 00:46:52.714 --> 00:46:55.593 According to the arrow, when NetMulticast is performed 604 00:46:56.233 --> 00:47:00.413 the server sends a message to the C1 character here 605 00:47:00.413 --> 00:47:03.233 This is fine because it has the MainUI 606 00:47:03.234 --> 00:47:06.273 Next, if you NetMulticast from the C2 character 607 00:47:06.273 --> 00:47:10.593 and the window on the C2 character to the C1 character, a message will be sent to this one 608 00:47:10.593 --> 00:47:15.573 So, who is the main character here? P1, this one 609 00:47:15.573 --> 00:47:18.413 C2 has the MainUI right now 610 00:47:19.073 --> 00:47:21.993 Attach it to the top of the screen 611 00:47:23.093 --> 00:47:25.333 and the UI bar like this 612 00:47:25.333 --> 00:47:28.293 Also add a crosshair here Who owns these as of now? 613 00:47:29.473 --> 00:47:35.294 This guy has the C2 character But does the C1 character here have a MainUI or not? 614 00:47:36.413 --> 00:47:40.473 No, there isn't one, so these things are displayed on his head 615 00:47:41.254 --> 00:47:45.913 However, we have created a receive function and other things in this MainUI 616 00:47:46.513 --> 00:47:49.954 We want to call the receive function in the MainUI 617 00:47:51.714 --> 00:47:56.533 but there is no MainUI right now So whose thing should we use? 618 00:47:56.533 --> 00:47:59.753 You have to use it using the MainUI this has 619 00:48:00.413 --> 00:48:02.873 That way, it will be displayed on the screen in the chat window 620 00:48:03.433 --> 00:48:09.034 So, this MainUI has to use the MainUI it has, so it doesn't have a MainUI right now 621 00:48:09.034 --> 00:48:12.814 So, how did we move the MainUI to where it is? 622 00:48:12.815 --> 00:48:15.234 I moved it to PlayerController 623 00:48:15.234 --> 00:48:16.993 Let's go to PlayerController 624 00:48:18.434 --> 00:48:24.433 If you look at my PlayerController, we've moved the MainUI from the character over here 625 00:48:24.433 --> 00:48:30.013 Because the MainUI was continuously created due to duplication, I moved it to PlayerController 626 00:48:30.013 --> 00:48:34.694 When the characters simply look at the MainUI in this PlayerController 627 00:48:36.713 --> 00:48:38.213 in the init UI widget 628 00:48:39.493 --> 00:48:40.233 when we take a look 629 00:48:41.733 --> 00:48:45.853 they just register and use the MainUI in the PlayerController like this 630 00:48:47.874 --> 00:48:52.193 Okay, what should we do when we want to receive 631 00:48:52.193 --> 00:48:55.253 and call the receive function? 632 00:48:55.253 --> 00:48:59.014 You can just take the MainUI in PlayerController and use it 633 00:48:59.015 --> 00:49:00.954 So let me do it like this 634 00:49:00.954 --> 00:49:04.273 To bring up the MainUI, we first need a PlayerController 635 00:49:04.273 --> 00:49:10.853 Auto PC requires Cast ANetPlayerController 636 00:49:13.074 --> 00:49:20.243 ANetPlayerController, you can get it from the world 637 00:49:20.293 --> 00:49:24.033 GetFirstPlayerController, like this 638 00:49:27.734 --> 00:49:36.944 And when we have a PlayerController, we want this to run 639 00:49:36.944 --> 00:49:41.914 So, you can call the receive message function here 640 00:49:41.914 --> 00:49:47.473 on the MainUI in PlayerController and insert Msg here 641 00:49:51.794 --> 00:49:57.053 This message will then appear on the screen in the MainUI 642 00:50:02.680 --> 00:50:06.340 Then, we just need to implement the receive message function 643 00:50:06.340 --> 00:50:09.160 Let's go to ReceiveMsg 644 00:50:09.160 --> 00:50:11.580 Now, if you come here and look at the receive function in the MainUI 645 00:50:13.740 --> 00:50:15.540 it looks like this 646 00:50:19.240 --> 00:50:22.760 Now, in the receive function, this is the content received from the server 647 00:50:22.760 --> 00:50:27.300 This is currently running on the client, why? Because it is UI 648 00:50:27.360 --> 00:50:28.200 Right? 649 00:50:32.719 --> 00:50:37.040 And what widget do we want to add to this scroll box is 650 00:50:37.040 --> 00:50:38.799 we want to add ChatWidget 651 00:50:38.799 --> 00:50:43.040 So auto chat Should I put it as msgWidget? 652 00:50:43.040 --> 00:50:45.690 Let's call it msgWidget 653 00:50:45.690 --> 00:50:49.279 This is a message to add to the scroll box 654 00:50:49.279 --> 00:50:52.040 Let's do CreateWidget 655 00:50:52.040 --> 00:50:56.119 Let's create a UChatWidget type here 656 00:50:56.119 --> 00:50:58.119 put GetWorld 657 00:50:58.119 --> 00:51:01.520 and put chatWidget 658 00:51:03.160 --> 00:51:07.840 We've already made it possible to receive chatWidget in the MainUI 659 00:51:11.680 --> 00:51:15.359 Then, in cpp, we want to create a widget 660 00:51:16.919 --> 00:51:22.039 and insert the created widget into the scroll box 661 00:51:22.039 --> 00:51:26.360 Then, there is no data in this msgWidget yet 662 00:51:26.360 --> 00:51:30.440 There's a message in it 663 00:51:30.440 --> 00:51:32.879 There is a widget called text message 664 00:51:32.879 --> 00:51:40.800 If you look closely at WBP ChatMsg, we set it as txt_msg 665 00:51:40.800 --> 00:51:45.040 If you enter message data here, the content will be included 666 00:51:47.760 --> 00:51:52.000 So, if you look at msgWidget 667 00:51:53.020 --> 00:51:54.740 it is said, txt_msg 668 00:51:55.720 --> 00:51:58.940 I haven't made it yet, so I'll add this part 669 00:52:01.440 --> 00:52:03.920 Go into ChatWidget.h 670 00:52:06.400 --> 00:52:11.820 Put public UPROPERTY 671 00:52:15.600 --> 00:52:17.759 BlueprintReadWrite 672 00:52:19.639 --> 00:52:24.119 meta, in fact, you don't have to write down BlueprintReadWrite 673 00:52:24.119 --> 00:52:26.179 Since we will not input data from the Blueprint 674 00:52:28.479 --> 00:52:32.560 we can simply put BindWidget here 675 00:52:34.360 --> 00:52:38.480 And it would be class UTextBlock 676 00:52:40.732 --> 00:52:43.992 txt_msg 677 00:52:46.520 --> 00:52:53.159 Let's add the relevant content to UChatWidget.h like this 678 00:52:53.159 --> 00:52:57.459 It is in, and then let's move to MainUI.cpp 679 00:52:59.559 --> 00:53:06.060 Then, the txt_msg will appear in the msg widget that you tried to insert earlier 680 00:53:08.080 --> 00:53:13.439 You can pass the msg received as this parameter 681 00:53:14.199 --> 00:53:17.080 Add SetText here 682 00:53:17.080 --> 00:53:23.800 Let's add FromString msg to FText like this 683 00:53:23.800 --> 00:53:30.020 Since it comes in as string data, you need to enter it as text data in FText format 684 00:53:32.360 --> 00:53:36.359 Let's add the msg widget created this way to the scroll box 685 00:53:39.092 --> 00:53:40.092 Scroll 686 00:53:43.320 --> 00:53:44.919 It hasn't been added 687 00:53:44.919 --> 00:53:46.960 Here's scroll_msgList 688 00:53:51.080 --> 00:53:55.440 Let me add it here by doing add a child 689 00:53:56.120 --> 00:53:59.939 Here, msgWidget 690 00:53:59.939 --> 00:54:02.720 Then, they will be added one by one to the scroll box 691 00:54:06.680 --> 00:54:12.839 Then, when we see this on the screen, we have to think more 692 00:54:12.839 --> 00:54:17.479 Here, we will print the message like this 693 00:54:17.479 --> 00:54:20.760 It is added like this, but what happens if the following message appears? 694 00:54:20.760 --> 00:54:26.600 A scroll bar like this should be added to automatically scroll here 695 00:54:28.860 --> 00:54:32.200 That's right, the scroll bar is now set to automatically appear on the screen 696 00:54:32.200 --> 00:54:36.559 But where should the current position of this scroll bar be? 697 00:54:37.399 --> 00:54:41.540 You have to move it to the bottom so it won't be visible on the screen 698 00:54:43.000 --> 00:54:46.839 So, I have to scroll to the bottom 699 00:54:46.839 --> 00:54:52.200 to see how this can get up there 700 00:54:52.200 --> 00:54:56.640 It goes up like this, and the whole thing has to go up like this 701 00:54:58.700 --> 00:55:02.120 to show the message at the bottom 702 00:55:03.880 --> 00:55:05.920 Like this 703 00:55:06.760 --> 00:55:11.320 So, to do this, if you call ScrolltoEnd 704 00:55:11.320 --> 00:55:16.200 in the scroll box and the scroll_msgList 705 00:55:16.200 --> 00:55:22.760 this is the code that brings the scroll box down to the bottom 706 00:55:24.340 --> 00:55:27.060 Then, it will move this scroll bar down on the screen 707 00:55:28.920 --> 00:55:32.559 If you look now, the thing that appears in red like this is because there is no UChatWidget 708 00:55:32.559 --> 00:55:35.799 Then, the scroll box is not declared 709 00:55:35.799 --> 00:55:39.620 Let me go up to the top and add it here 710 00:55:41.000 --> 00:55:44.260 Let's #include 711 00:55:46.440 --> 00:55:53.459 and add ScrollBox.h to the component like this 712 00:55:57.720 --> 00:56:02.600 Now, we need one more, ChatWidget 713 00:56:02.600 --> 00:56:09.339 ChatWidget must be added here as a header file for use 714 00:56:11.620 --> 00:56:14.559 Let's include two header files 715 00:56:20.079 --> 00:56:24.559 Shall we try building next? 716 00:56:28.132 --> 00:56:29.400 Then 717 00:56:29.400 --> 00:56:34.579 you can see here that the UText block is currently being used 718 00:56:34.580 --> 00:56:36.419 but not included 719 00:56:36.419 --> 00:56:40.999 So, let's add TextBlock to the top of the header file 720 00:56:43.072 --> 00:56:45.392 So, let's #include 721 00:56:45.392 --> 00:56:51.399 and add TextBlock .h under the component like this 722 00:56:51.399 --> 00:56:52.899 Then let's build again 723 00:56:56.332 --> 00:57:00.152 So let's move on to Unreal Editor 724 00:57:00.152 --> 00:57:04.279 Since a lot has been added, I'll close it and turn it back on 725 00:57:18.239 --> 00:57:23.719 When Unreal Editor opens, move to the WBP MainUI 726 00:57:27.319 --> 00:57:30.279 From here, you come to the graph window 727 00:57:30.280 --> 00:57:34.519 In Class Default, we now need ChatWidget 728 00:57:34.519 --> 00:57:39.052 So, if you select ChatWidget like this 729 00:57:39.052 --> 00:57:41.252 if you search here, ChatWidget will appear 730 00:57:42.472 --> 00:57:45.032 There's nothing here right now 731 00:57:45.032 --> 00:57:48.519 so let's open it and add the WBP_ChatWidget here 732 00:57:50.079 --> 00:57:52.020 Okay, click compile 733 00:57:56.000 --> 00:57:59.380 Next, let's go into the main map of the Third Person 734 00:58:01.851 --> 00:58:03.811 Now, press the play button 735 00:58:03.811 --> 00:58:08.460 So it looks like this here Let's open one more player 736 00:58:12.920 --> 00:58:18.979 In the server window before inserting the message, let's say hello and press send 737 00:58:20.751 --> 00:58:22.111 Then, what happens? 738 00:58:22.111 --> 00:58:27.919 You can check that the message is sent normally from the server and stamped as "Hello" 739 00:58:32.679 --> 00:58:37.579 Then, "Hello" is stamped here, and "Hello" is stamped on the client 740 00:58:37.591 --> 00:58:42.811 Then, let's say "Okay, hi" from client, then send 741 00:58:43.531 --> 00:58:44.419 Then 742 00:58:44.419 --> 00:58:47.719 On both side, "Okay, hi" is well shown 743 00:58:47.719 --> 00:58:53.831 Client sent "Okay, hi" Server sent it and received it too 744 00:58:53.831 --> 00:58:55.631 So here we have a server 745 00:58:55.631 --> 00:58:58.540 Here, it's client, and this too 746 00:58:58.540 --> 00:59:03.020 The client sent a Server RPC to the server, and then 747 00:59:03.020 --> 00:59:06.411 the server sent NetMulticast to all clients 748 00:59:06.411 --> 00:59:09.551 and the screen is currently in this state 749 00:59:12.080 --> 00:59:14.831 There are three types of RPC 750 00:59:14.831 --> 00:59:18.920 Server RPC, then Client RPC, and NetMulticast RPC 751 00:59:18.920 --> 00:59:22.239 If you have a clear understanding of these concepts 752 00:59:22.831 --> 00:59:26.831 you can easily implement chatting in no time 753 00:59:28.599 --> 00:59:31.680 We have implemented the chat logic up to this point 754 00:59:32.451 --> 00:59:35.851 Let's wrap up what we learned in this lecture 755 00:59:35.851 --> 00:59:37.191 Create Chat UI Constructs a UI that allows chat communication between users within the game 756 00:59:37.191 --> 00:59:38.632 The client sends a message to Server RPC, and the server sends a message to Client RPC 757 00:59:38.632 --> 00:59:40.051 The server has a PlayerController and can send messages to all clients 758 00:59:40.052 --> 00:59:41.471 Creating a UserWidget to display chat UI 759 00:59:41.472 --> 00:59:42.791 Creating a chat window with a message input window and a Send button 760 00:59:42.791 --> 00:59:44.012 Implement Chat Logic 761 00:59:44.012 --> 00:59:45.672 Implements chat logic between multiple users using Server RPC and NetMulticast RPC 762 00:59:45.672 --> 00:59:47.207 NetMulticast RPC does not work in PlayerController because the server holds PlayerControllers for all users 763 00:59:47.208 --> 00:59:48.467 This is because the client has its own PlayerController 764 00:59:48.467 --> 00:59:50.127 To use NetMulticast, all clients in the world, including the server, must have the same Actor 765 00:59:50.127 --> 00:59:51.127 The End