WEBVTT 1 00:00:27.600 --> 00:00:29.640 Hello, this is Youngho Lee 2 00:00:29.640 --> 00:00:34.080 In this unit, we'll learn take pistol and release pistol actions 3 00:00:34.080 --> 00:00:36.280 Unlike single play 4 00:00:36.280 --> 00:00:39.880 we'll use actor replication 5 00:00:39.880 --> 00:00:43.280 when character takes or releases pistol 6 00:00:43.280 --> 00:00:46.400 on network, and how to sync the data between players 7 00:00:46.400 --> 00:00:50.200 The first thing we'll study is taking pistol 8 00:00:50.200 --> 00:00:51.320 To do this 9 00:00:51.320 --> 00:00:56.200 you'll use owner setting, server RPC and NetMulticast RPC 10 00:00:56.200 --> 00:00:59.119 And to sync the take pistol animation 11 00:00:59.119 --> 00:01:02.240 we'll learn how to use property replication 12 00:01:02.240 --> 00:01:05.080 Secondly, we'll learn release pistol 13 00:01:05.080 --> 00:01:08.599 Similarly, we'll use RPC 14 00:01:08.599 --> 00:01:11.949 and separate the logic that the server will process and 15 00:01:11.949 --> 00:01:13.300 the one that the client will 16 00:01:13.706 --> 00:01:16.306 Take pistol 17 00:01:18.480 --> 00:01:19.940 First is take pistol 18 00:01:21.320 --> 00:01:23.040 Let's see 19 00:01:23.040 --> 00:01:24.919 We'll first learn Standalone 20 00:01:24.919 --> 00:01:28.080 that is, single player, and then multiplayer 21 00:01:28.080 --> 00:01:31.680 We'll divide it into these two situations 22 00:01:31.680 --> 00:01:33.360 The one on the left is Standalone 23 00:01:33.360 --> 00:01:34.800 single player 24 00:01:36.040 --> 00:01:40.839 On Standalone, you'll get an input 25 00:01:40.839 --> 00:01:42.440 for take pistol 26 00:01:42.440 --> 00:01:44.279 then you'll set the owner 27 00:01:44.279 --> 00:01:46.839 and will actually take the pistol 28 00:01:46.839 --> 00:01:48.760 With the take pistol input 29 00:01:48.760 --> 00:01:49.959 owner setting takes place 30 00:01:49.959 --> 00:01:52.400 and lastly attaching 31 00:01:52.400 --> 00:01:55.000 so that the pistol is attached to me 32 00:01:55.000 --> 00:01:57.680 This is what we'll do on Standalone 33 00:01:57.680 --> 00:01:59.519 single game situations 34 00:01:59.519 --> 00:02:01.440 But in network 35 00:02:01.440 --> 00:02:05.040 when there are server and client coexisting, take pistol can 36 00:02:05.040 --> 00:02:08.639 have errors if it uses this flow 37 00:02:08.639 --> 00:02:10.839 What might happen is the client took a pistol 38 00:02:10.839 --> 00:02:12.519 but other clients 39 00:02:12.519 --> 00:02:15.360 or the server might not be able to know 40 00:02:15.360 --> 00:02:16.959 that this client took a pistol 41 00:02:16.959 --> 00:02:19.320 This is Standalone 42 00:02:19.320 --> 00:02:21.720 Then let's expand this 43 00:02:21.720 --> 00:02:23.120 to multiplayer 44 00:02:23.120 --> 00:02:25.220 network mode where many players can join 45 00:02:26.440 --> 00:02:27.680 It's the diagram on the right 46 00:02:27.680 --> 00:02:29.519 Client, similar 47 00:02:29.519 --> 00:02:31.800 to Standalone, gets input 48 00:02:31.800 --> 00:02:33.239 They get input first 49 00:02:33.239 --> 00:02:36.960 and then with this input, they'll request 50 00:02:36.960 --> 00:02:39.820 the server using server RPC to take a pistol 51 00:02:42.000 --> 00:02:43.000 Different right? 52 00:02:43.000 --> 00:02:44.160 On Standalone, 53 00:02:44.160 --> 00:02:46.720 they just set owner and took the pistol themselves 54 00:02:46.720 --> 00:02:49.160 but here, the client isn't taking the pistol themself 55 00:02:49.160 --> 00:02:52.600 but requesting the server to do that 56 00:02:52.600 --> 00:02:58.199 Then the server will receive the request from the client 57 00:02:58.199 --> 00:03:00.679 and do owner setting 58 00:03:00.679 --> 00:03:03.720 and after that's done 59 00:03:03.720 --> 00:03:06.360 tell's them that they can take the pistol 60 00:03:06.360 --> 00:03:09.279 so they will attach 61 00:03:09.279 --> 00:03:11.559 the pistol to the hands of 62 00:03:11.559 --> 00:03:13.759 the client which is done 63 00:03:13.759 --> 00:03:14.960 by the client 64 00:03:14.960 --> 00:03:17.600 Why? Because that's a visual aspect 65 00:03:17.600 --> 00:03:19.360 This part, the server can't do 66 00:03:19.360 --> 00:03:21.600 and the client must 67 00:03:21.600 --> 00:03:23.880 So the server's role is 68 00:03:23.880 --> 00:03:27.960 to get the input from the client 69 00:03:27.960 --> 00:03:30.520 and to test range 70 00:03:30.520 --> 00:03:34.720 and set owner 71 00:03:34.720 --> 00:03:37.679 Owner setting must be done in the server 72 00:03:37.679 --> 00:03:39.479 I've been telling you this 73 00:03:39.479 --> 00:03:41.039 but if owner setting is done by clients 74 00:03:41.039 --> 00:03:44.919 the server or other client can't know about that 75 00:03:44.919 --> 00:03:46.440 so communication is impossible 76 00:03:46.440 --> 00:03:48.240 Owner setting must be done by the server 77 00:03:48.240 --> 00:03:50.600 so that the owner's 78 00:03:50.600 --> 00:03:53.199 net connection object can communicate 79 00:03:54.559 --> 00:03:58.720 The server receives request and sets owner 80 00:03:58.720 --> 00:04:01.279 then to all clients 81 00:04:01.279 --> 00:04:04.880 it will send take pistol request saying 'this person's going to take a pistol' 82 00:04:04.880 --> 00:04:06.919 Then all clients will 83 00:04:06.919 --> 00:04:09.279 get this message 84 00:04:09.279 --> 00:04:13.179 and do the logic that makes that client take a pistol 85 00:04:16.240 --> 00:04:18.279 The overall flow is like this 86 00:04:18.279 --> 00:04:22.399 Then let's make this using codes and 87 00:04:22.399 --> 00:04:25.479 Unreal Engine editor 88 00:04:25.479 --> 00:04:28.079 First let's go to Visual Studio 89 00:04:32.759 --> 00:04:37.700 On Visual Studio 90 00:04:39.080 --> 00:04:44.039 until now, we used this NetActor for RPC 91 00:04:44.039 --> 00:04:46.720 and property replication 92 00:04:46.720 --> 00:04:48.840 but now we'll 93 00:04:48.840 --> 00:04:53.440 learn about NetTPSCharacter multiplayer 94 00:04:53.440 --> 00:04:56.479 So first, on Visual Studio 95 00:05:00.419 --> 00:05:02.959 let's go to NetTPSCharacter 96 00:05:02.959 --> 00:05:05.040 We'll go to the header file 97 00:05:05.040 --> 00:05:07.880 Go to NetTPSCharacter header file 98 00:05:07.880 --> 00:05:09.780 and on the very bottom 99 00:05:11.140 --> 00:05:13.759 It says network related member here 100 00:05:15.799 --> 00:05:18.199 Here, to separate 101 00:05:18.199 --> 00:05:21.219 I'll add public 102 00:05:21.219 --> 00:05:25.239 We're going to add the part that sends the take pistol message with a server RPC 103 00:05:25.239 --> 00:05:31.079 UFUNCTION, and we needed to put server option for server RPC 104 00:05:31.079 --> 00:05:34.160 Then take pistol must be performed 105 00:05:34.160 --> 00:05:36.900 So we'll put reliable 106 00:05:38.380 --> 00:05:45.559 void, ServerRPC, TakePistol 107 00:05:48.279 --> 00:05:51.519 You can put an underscore between the serverRPC 108 00:05:51.519 --> 00:05:54.160 and TakePistol or not, it doesn't really matter 109 00:05:54.160 --> 00:05:57.480 You can do as you want 110 00:05:57.480 --> 00:06:00.480 For the function name, we just need to say that 111 00:06:00.480 --> 00:06:02.679 it's a server RPC function 112 00:06:02.679 --> 00:06:04.220 Then when we build 113 00:06:05.961 --> 00:06:08.081 on the generated header file 114 00:06:10.000 --> 00:06:13.519 server RPC function implementation is added 115 00:06:13.519 --> 00:06:16.440 And what we actually need to implement 116 00:06:16.440 --> 00:06:18.480 is not the ServerRPC TakePistol 117 00:06:18.480 --> 00:06:24.130 but ServerRPCTakePistol_Implementation 118 00:06:24.130 --> 00:06:26.440 This is the one 119 00:06:26.440 --> 00:06:33.359 So on NetTPSCharacter.cpp, ServerRPC TakePistol_Implementation 120 00:06:33.359 --> 00:06:36.200 We need to put the function name like this 121 00:06:36.200 --> 00:06:40.720 Then internally, ServerRPC TakePistol function is implemented 122 00:06:40.720 --> 00:06:43.470 and in that function, this implementation 123 00:06:43.470 --> 00:06:46.059 will be called 124 00:06:49.959 --> 00:06:52.060 Like this, implementation is added 125 00:06:54.600 --> 00:06:59.239 Then, with this ServerRPC TakePistol part 126 00:06:59.239 --> 00:07:03.279 we need to move the take pistol parts 127 00:07:03.279 --> 00:07:07.720 I'll move this function's placement first so that it can be close to 128 00:07:07.720 --> 00:07:11.299 TakePistol function 129 00:07:11.299 --> 00:07:16.239 I'll move it next to the TakePistol function 130 00:07:16.239 --> 00:07:20.760 I'll put it under it here 131 00:07:22.880 --> 00:07:24.159 so that it's easier to see 132 00:07:26.579 --> 00:07:29.300 Here, this part down here 133 00:07:30.600 --> 00:07:33.279 If we have a pistol or not 134 00:07:33.279 --> 00:07:35.000 can be checked here 135 00:07:35.000 --> 00:07:38.000 This doesn't need to be given to the server 136 00:07:38.000 --> 00:07:40.799 That could waste packets 137 00:07:40.799 --> 00:07:44.140 So under here, if one has a pistol 138 00:07:46.480 --> 00:07:48.399 we return and not perform anything 139 00:07:48.399 --> 00:07:51.119 and when one doesn't 140 00:07:51.119 --> 00:07:53.359 this part down here is subject to checking 141 00:07:53.359 --> 00:07:55.239 So it will be the part of taking a pistol 142 00:07:57.839 --> 00:08:00.119 This part all moves to where? 143 00:08:00.119 --> 00:08:04.480 To ServerRPC TakePistol 144 00:08:04.480 --> 00:08:06.959 I'll cut this part 145 00:08:06.959 --> 00:08:09.559 from TakePistol 146 00:08:09.559 --> 00:08:14.380 and paste it here on ServerRPC TakePistol 147 00:08:16.559 --> 00:08:21.399 Then it will be moved to 148 00:08:21.399 --> 00:08:23.280 ServerRPC TakePistol Implementation 149 00:08:26.680 --> 00:08:29.600 Then on TakePistol 150 00:08:29.600 --> 00:08:33.320 This is a function that is called when input is received 151 00:08:33.320 --> 00:08:37.219 It requests to the server when that happens 152 00:08:38.359 --> 00:08:40.160 Like I explained with the diagram 153 00:08:40.160 --> 00:08:42.959 now we're on request to server 154 00:08:42.959 --> 00:08:45.640 so it has to request to the server saying 155 00:08:45.640 --> 00:08:47.880 'I'm going to take a pistol' 156 00:08:47.880 --> 00:08:50.819 This is ServerRPC TakePistol 157 00:08:52.159 --> 00:08:56.079 So the request code here 158 00:08:56.079 --> 00:09:00.960 will be ServerRPCTakePistol 159 00:09:00.960 --> 00:09:03.960 If we directly call using Implementation 160 00:09:03.960 --> 00:09:06.400 This isn't from client to server 161 00:09:06.400 --> 00:09:08.239 but when it is the server, calling itself 162 00:09:08.239 --> 00:09:09.880 it being the server itself 163 00:09:09.880 --> 00:09:12.799 Server can call with its own function 164 00:09:12.799 --> 00:09:15.919 But when this is a client 165 00:09:15.919 --> 00:09:17.840 when processing an input from a client 166 00:09:17.840 --> 00:09:21.000 it isn't the server itself so it can't call this function 167 00:09:21.000 --> 00:09:25.159 If it's called 168 00:09:25.159 --> 00:09:26.479 internally 169 00:09:26.479 --> 00:09:29.119 if server RPC interally works 170 00:09:29.119 --> 00:09:30.479 calling this function 171 00:09:30.479 --> 00:09:32.229 then this function will be 172 00:09:32.229 --> 00:09:34.679 internally called 173 00:09:34.679 --> 00:09:37.840 so if we call it here directly 174 00:09:37.840 --> 00:09:39.479 from the client 175 00:09:39.479 --> 00:09:42.000 this can cause a problem, why? 176 00:09:42.000 --> 00:09:44.320 Because this isn't the server 177 00:09:44.320 --> 00:09:48.320 This is a client, so it can't call a server's function 178 00:09:48.320 --> 00:09:50.320 It has to be using an RPC function to call 179 00:09:50.320 --> 00:09:54.580 and this function being called inside the RPC 180 00:09:56.200 --> 00:09:59.960 Now, the client has sent 181 00:09:59.960 --> 00:10:01.719 a request to the server 182 00:10:01.719 --> 00:10:04.239 We're here 183 00:10:04.239 --> 00:10:07.320 Client requesting the server 184 00:10:07.320 --> 00:10:11.200 This part just took place 185 00:10:11.200 --> 00:10:14.359 Then the server must do the logic of 186 00:10:14.359 --> 00:10:17.509 setting the owner and 187 00:10:17.509 --> 00:10:18.799 sending message to all clients 188 00:10:18.799 --> 00:10:20.520 Then take pistol 189 00:10:20.520 --> 00:10:23.359 the attach part 190 00:10:23.359 --> 00:10:25.520 must be done in the client 191 00:10:25.520 --> 00:10:28.239 The server only requests to attach 192 00:10:28.239 --> 00:10:33.159 Right? 193 00:10:33.159 --> 00:10:34.840 Great 194 00:10:34.840 --> 00:10:37.500 Then let's first build 195 00:10:46.000 --> 00:10:49.280 and see how it turns out 196 00:10:49.280 --> 00:10:53.320 We can easily guess what that would be 197 00:10:53.320 --> 00:10:54.640 Input comes in 198 00:10:54.640 --> 00:10:56.719 Then it requests to the server 199 00:10:56.719 --> 00:10:59.919 It'll say 'I want to take a pistol' 200 00:10:59.919 --> 00:11:05.520 Then the server will call this function internally 201 00:11:05.520 --> 00:11:08.479 and the take pistol will take place 202 00:11:08.479 --> 00:11:12.720 Then let's think about the case where there are two clients 203 00:11:14.200 --> 00:11:17.799 Let's say one's here 204 00:11:17.799 --> 00:11:21.019 and another one's here 205 00:11:23.699 --> 00:11:25.359 Then 206 00:11:25.359 --> 00:11:28.159 This client is 207 00:11:28.159 --> 00:11:29.440 in the server 208 00:11:29.440 --> 00:11:31.640 We'll call this one C1 209 00:11:31.640 --> 00:11:34.679 and this one C2 210 00:11:34.679 --> 00:11:38.520 This one is in the server 211 00:11:38.520 --> 00:11:41.559 Here, let's say that C2 212 00:11:41.559 --> 00:11:44.140 requests ServerRPCPistol 213 00:11:45.760 --> 00:11:48.400 Right, then this screen 214 00:11:48.400 --> 00:11:50.919 where these two are in, no matter the server or client 215 00:11:50.919 --> 00:11:52.840 will show both of them 216 00:11:52.840 --> 00:11:54.880 When in this situation 217 00:11:54.880 --> 00:11:56.320 ServerRPC is requested 218 00:11:56.320 --> 00:11:59.799 For C1, taking pistol code 219 00:11:59.799 --> 00:12:01.960 will be performed 220 00:12:01.960 --> 00:12:04.479 So it will take a pistol 221 00:12:05.939 --> 00:12:08.400 But for C2 222 00:12:08.400 --> 00:12:10.280 this thing is perfromed in the server 223 00:12:10.280 --> 00:12:12.520 but it hasn't sent the request 224 00:12:12.520 --> 00:12:14.520 to other clients yet 225 00:12:14.520 --> 00:12:16.799 so this guy, even though 226 00:12:16.799 --> 00:12:19.679 this C2 is going to take the pistol can it take it or no? 227 00:12:19.679 --> 00:12:22.919 It can't 228 00:12:22.919 --> 00:12:25.320 The re-request hasn't come yet 229 00:12:25.359 --> 00:12:26.799 The server will already have 230 00:12:26.799 --> 00:12:28.520 performed the things down here 231 00:12:28.520 --> 00:12:30.520 so it will take the pistol 232 00:12:30.520 --> 00:12:32.159 But the client, even though 233 00:12:32.159 --> 00:12:34.200 it requested to the server 234 00:12:34.200 --> 00:12:36.280 hasn't received the request from the server 235 00:12:36.280 --> 00:12:39.080 telling it to take a pistol 236 00:12:39.080 --> 00:12:43.039 so it can't take the pistol 237 00:12:43.039 --> 00:12:44.679 So when we run it 238 00:12:44.679 --> 00:12:48.520 the character in the server will take a pistol 239 00:12:48.520 --> 00:12:52.679 but will client's screen show it taking the pistol? 240 00:12:52.679 --> 00:12:53.880 It won't 241 00:12:53.880 --> 00:12:55.740 Let's check that 242 00:12:58.760 --> 00:13:00.959 Let's run two of these 243 00:13:03.039 --> 00:13:04.059 Great 244 00:13:05.039 --> 00:13:10.039 First, look at the server screen 245 00:13:10.039 --> 00:13:13.359 To perform both of them 246 00:13:13.359 --> 00:13:17.679 I'll check on New Editor Window 247 00:13:17.679 --> 00:13:19.239 Not Selected Viewport 248 00:13:19.239 --> 00:13:21.640 Let's do New Editor Window 249 00:13:21.640 --> 00:13:26.159 Then, on the window 250 00:13:26.159 --> 00:13:27.919 it says server 251 00:13:27.919 --> 00:13:29.400 This is the server window 252 00:13:29.400 --> 00:13:31.000 and let me open a client window 253 00:13:31.000 --> 00:13:33.559 next to it 254 00:13:33.559 --> 00:13:36.520 Let me do that 255 00:13:38.320 --> 00:13:41.119 The one on the left is the server 256 00:13:41.119 --> 00:13:43.840 and the right is the client 257 00:13:43.840 --> 00:13:46.640 Let me take the pistol from the server screen 258 00:13:46.640 --> 00:13:50.700 Then to the client, it should show the server character taking the pistol 259 00:13:50.700 --> 00:13:52.680 but as I told you 260 00:13:52.680 --> 00:13:56.840 client doesn't receive any RPC 261 00:13:56.840 --> 00:13:58.340 so the server character taking a pistol 262 00:13:58.340 --> 00:14:00.039 will show on the client's screen or no? 263 00:14:00.039 --> 00:14:00.840 It won't 264 00:14:00.840 --> 00:14:04.840 On the other hand on the server's screen 265 00:14:04.840 --> 00:14:06.880 you can see it 266 00:14:06.880 --> 00:14:07.540 Right 267 00:14:08.880 --> 00:14:10.760 But the client 268 00:14:10.760 --> 00:14:13.299 can't see anything 269 00:14:20.799 --> 00:14:23.119 The server shows taking the pistol 270 00:14:23.119 --> 00:14:25.440 but on the client window on the right 271 00:14:25.440 --> 00:14:28.320 it doesn't show the server character taking anything 272 00:14:28.320 --> 00:14:31.039 Why? On the server 273 00:14:31.039 --> 00:14:33.479 the take pistol logic was performed 274 00:14:33.479 --> 00:14:36.579 but a request to the client to take a pistol 275 00:14:36.579 --> 00:14:37.679 was not sent 276 00:14:37.679 --> 00:14:39.100 so this problem occurs 277 00:14:42.080 --> 00:14:46.000 So now let's solve that 278 00:14:46.000 --> 00:14:49.719 For that, for every character to take pistols 279 00:14:50.559 --> 00:14:53.640 we'll use a 280 00:14:53.640 --> 00:14:56.080 NetMulticast RPC 281 00:14:56.080 --> 00:14:59.359 Go to NetTPSCharacter's header file 282 00:14:59.359 --> 00:15:01.960 and under server RPC 283 00:15:01.960 --> 00:15:06.840 we'll put NetMulticastRPC 284 00:15:06.840 --> 00:15:12.520 This time, instead of server, we'll have NetMulticast 285 00:15:12.520 --> 00:15:15.960 and then void Multicast 286 00:15:15.960 --> 00:15:20.960 Then MulticastRPC_TakePistol 287 00:15:20.960 --> 00:15:27.039 And here, const a actor pistol actor 288 00:15:27.039 --> 00:15:29.119 I'll put that here 289 00:15:31.039 --> 00:15:34.479 Why? This part needs to tell the clients 290 00:15:34.479 --> 00:15:36.159 what pistol to take 291 00:15:36.159 --> 00:15:38.800 so we're going to have a parameter here 292 00:15:40.960 --> 00:15:46.200 We'll add implementation under the server RPC 293 00:15:46.200 --> 00:15:52.919 Under server RPC, NetMulticastRPC TakePistol is implemented 294 00:15:52.919 --> 00:15:57.159 There's also _implementation as well 295 00:15:57.159 --> 00:15:58.000 for the same reason 296 00:15:59.960 --> 00:16:01.840 Great 297 00:16:01.840 --> 00:16:06.960 Then the server RPC calls this MulticastRPC 298 00:16:06.960 --> 00:16:08.810 and MulticastRPC 299 00:16:08.810 --> 00:16:12.400 needs taking pistol part 300 00:16:12.400 --> 00:16:13.900 As you see in the screen 301 00:16:15.000 --> 00:16:18.080 the taking pistol part 302 00:16:18.080 --> 00:16:21.400 isn't here but in the server 303 00:16:21.400 --> 00:16:23.700 So like in this diagram 304 00:16:24.840 --> 00:16:27.520 after the owner setting part 305 00:16:27.520 --> 00:16:28.919 and the taking pistol part 306 00:16:28.919 --> 00:16:31.880 actually attaching the pistol to the actor 307 00:16:31.880 --> 00:16:36.000 and such must be done by the clients with Multicast 308 00:16:36.000 --> 00:16:37.580 We'll move those here 309 00:16:40.280 --> 00:16:45.200 So on MulticastRPC, we'll add 310 00:16:47.680 --> 00:16:48.799 attach pistol, this part 311 00:16:48.799 --> 00:16:52.080 We need this part not here, but under here 312 00:16:52.080 --> 00:16:53.139 We'll do that 313 00:16:54.639 --> 00:16:55.600 Attach pistol 314 00:16:57.140 --> 00:16:59.520 Above here, owner setting 315 00:16:59.520 --> 00:17:03.180 and data setting will be done where? 316 00:17:03.180 --> 00:17:05.280 On the server 317 00:17:06.880 --> 00:17:13.280 Under here, MulticastRPC TakePistol 318 00:17:13.280 --> 00:17:17.479 and we'll put what's to be attached 319 00:17:17.479 --> 00:17:20.880 That will be Pistol actor 320 00:17:20.880 --> 00:17:22.960 Put the pistol to be attached 321 00:17:22.960 --> 00:17:25.780 and the message will be sent to clients 322 00:17:27.840 --> 00:17:29.440 It looks like simply calling a function 323 00:17:29.440 --> 00:17:31.719 but communication happens internally 324 00:17:31.719 --> 00:17:36.079 So the server sends to clients 325 00:17:36.079 --> 00:17:38.920 MulticastRPC with the message telling 326 00:17:38.920 --> 00:17:42.199 to take pistol, TakePistol is internally sent 327 00:17:42.199 --> 00:17:45.440 Then the function is called in the client 328 00:17:47.920 --> 00:17:51.399 Let's build 329 00:17:52.119 --> 00:17:54.160 This is an RPC function 330 00:17:54.160 --> 00:17:56.680 so it's the server and a client 331 00:17:56.680 --> 00:17:57.880 It's both 332 00:17:57.880 --> 00:18:02.319 I did all this in the server and did Multicast 333 00:18:02.319 --> 00:18:05.719 It's the server and a client at the same time 334 00:18:05.719 --> 00:18:08.800 but they are logically separate 335 00:18:08.800 --> 00:18:11.439 Physically the server and client is together 336 00:18:11.439 --> 00:18:16.880 but logically, C1 and C2 are separate 337 00:18:16.880 --> 00:18:20.239 So now, C2 has RPC requested 338 00:18:20.239 --> 00:18:23.599 to the server saying 'I want to take a pistol' 339 00:18:23.599 --> 00:18:25.599 Then the server 340 00:18:25.599 --> 00:18:27.959 does all this 341 00:18:27.959 --> 00:18:29.280 and sends a Multicast 342 00:18:29.280 --> 00:18:31.959 How? It sends this 343 00:18:31.959 --> 00:18:34.199 to all clients 344 00:18:34.199 --> 00:18:37.119 Although this is physically here together 345 00:18:37.119 --> 00:18:41.160 but this is ultimately like this logically 346 00:18:41.160 --> 00:18:43.400 So from server to client 347 00:18:43.400 --> 00:18:45.799 message is sent with Multicast 348 00:18:46.402 --> 00:18:47.402 Got it? 349 00:18:49.599 --> 00:18:53.340 Then the client will perform take pistol 350 00:18:55.400 --> 00:18:57.699 Let's build 351 00:19:04.319 --> 00:19:06.800 And we'll run 352 00:19:06.800 --> 00:19:09.239 but let's think about what problem might happen 353 00:19:09.239 --> 00:19:10.519 when we run it 354 00:19:13.102 --> 00:19:14.102 Play 355 00:19:15.199 --> 00:19:18.459 Server open, and client as well 356 00:19:21.959 --> 00:19:25.400 I'll take the pistol from the server screen 357 00:19:25.400 --> 00:19:28.260 Then what will happen 358 00:19:29.520 --> 00:19:31.320 It suddenly stops 359 00:19:32.640 --> 00:19:34.759 and the editor shuts off 360 00:19:36.099 --> 00:19:39.119 Why? Analyzing the error message 361 00:19:42.839 --> 00:19:45.880 Here, it says NetTPS Crash Repoter 362 00:19:45.880 --> 00:19:47.520 Don't skip this 363 00:19:47.520 --> 00:19:50.199 It shows what errors happened 364 00:19:50.199 --> 00:19:54.040 Here, it says exception error 365 00:19:54.040 --> 00:19:57.419 Access violation, reading access, and then null 366 00:19:58.839 --> 00:20:01.560 A null subject 367 00:20:02.622 --> 00:20:04.961 There's no value in the pointer 368 00:20:04.961 --> 00:20:08.041 I entered that place so an error occured 369 00:20:08.062 --> 00:20:11.122 Look 370 00:20:11.122 --> 00:20:13.262 There was an error in show crosshair of mainUI 371 00:20:13.263 --> 00:20:16.642 and on the ninth line of mainUI cpp 372 00:20:16.642 --> 00:20:19.161 this occured 373 00:20:19.161 --> 00:20:23.981 Let's go to ninth of mainUI 374 00:20:25.562 --> 00:20:30.142 Go to ninth line of mainUI cpp 375 00:20:30.143 --> 00:20:33.902 Let's see what it is 376 00:20:33.902 --> 00:20:36.721 show cross needs to show this but 377 00:20:36.722 --> 00:20:39.661 there are no image crosshair 378 00:20:39.661 --> 00:20:43.881 Then we'll need to move to where it called these show crosshair 379 00:20:44.861 --> 00:20:47.760 That being nonexistent 380 00:20:51.420 --> 00:20:55.241 There was no problem here 381 00:20:55.241 --> 00:20:57.902 Where it called this 382 00:20:57.902 --> 00:21:00.762 That's AttachPistol 383 00:21:01.842 --> 00:21:06.662 It's this part 384 00:21:06.662 --> 00:21:11.601 It was going to receive Multicast, attach pistol and when doing that 385 00:21:11.602 --> 00:21:14.221 attach all these onto component 386 00:21:14.221 --> 00:21:19.561 and do this on the mainUI and show crosshair 387 00:21:19.562 --> 00:21:22.401 But looking here, mainUI 388 00:21:22.401 --> 00:21:25.721 is null so this part caused the error 389 00:21:25.742 --> 00:21:27.742 I'll put a breakpoint here 390 00:21:28.881 --> 00:21:31.820 Then we'll perform it on debug mode 391 00:21:40.240 --> 00:21:42.090 When working with Unreal 392 00:21:42.090 --> 00:21:45.520 performing debug mode on Visual Studio 393 00:21:45.521 --> 00:21:47.881 is pretty useful on finding runtime errors 394 00:21:47.881 --> 00:21:50.281 I'll play it again 395 00:21:50.282 --> 00:21:52.541 and also a client window 396 00:21:52.561 --> 00:21:57.841 I'll go forward and take with F, it says this 397 00:22:00.922 --> 00:22:03.761 Here, the error happened 398 00:22:03.781 --> 00:22:08.400 here on the Net Nulticast TakePistol 399 00:22:08.400 --> 00:22:11.321 On Net Nulticast TakePistol 400 00:22:13.842 --> 00:22:14.842 Right here 401 00:22:16.002 --> 00:22:18.662 This part was where the error happened 402 00:22:18.662 --> 00:22:22.462 So the mainUI 403 00:22:22.462 --> 00:22:23.462 there's no memory here 404 00:22:23.462 --> 00:22:26.642 which means it's null here 405 00:22:26.642 --> 00:22:29.001 so we need a code here 406 00:22:29.002 --> 00:22:31.152 Then why does this problem happen? 407 00:22:31.152 --> 00:22:33.881 Why is there nothing in here? 408 00:22:33.881 --> 00:22:36.100 That's because of these 409 00:22:37.921 --> 00:22:41.700 Let me use this picture to explain 410 00:22:45.040 --> 00:22:46.680 So here 411 00:22:49.180 --> 00:22:53.502 PC means player controller 412 00:22:53.502 --> 00:22:56.681 and this one also means player controller 413 00:22:56.681 --> 00:23:03.801 NetMulticast will be sent 414 00:23:03.801 --> 00:23:06.442 It will call 415 00:23:06.442 --> 00:23:12.022 I said that NetMulticast is Actor Replication 416 00:23:14.202 --> 00:23:17.682 This literally means actor 417 00:23:17.682 --> 00:23:22.361 It means that when the same object is in a world they can communicate 418 00:23:22.362 --> 00:23:23.781 with each other 419 00:23:23.781 --> 00:23:25.501 It means communicating using actor 420 00:23:25.502 --> 00:23:27.541 Actor replication 421 00:23:27.541 --> 00:23:33.401 Then looking at the mainUI 422 00:23:33.401 --> 00:23:38.040 what were the conditions of this being made 423 00:23:38.040 --> 00:23:39.721 Let's take a look at the code 424 00:23:42.120 --> 00:23:46.640 It says InitUIWidget 425 00:23:49.082 --> 00:23:51.262 From here 426 00:23:51.262 --> 00:23:54.302 Do not process if player is not controlling 427 00:23:54.302 --> 00:23:58.482 So if there's no player mainUI is not made 428 00:23:58.482 --> 00:24:02.581 Right? Do not process if player is not controlling 429 00:24:04.002 --> 00:24:05.602 Going back to the screen 430 00:24:06.942 --> 00:24:09.822 We sent a NetMulticast 431 00:24:09.822 --> 00:24:14.122 But the mainUI must have a player controller on that phone 432 00:24:14.122 --> 00:24:18.241 Only then the code logic runs 433 00:24:18.241 --> 00:24:22.360 We're saying that there are these two clients 434 00:24:22.360 --> 00:24:24.962 Both will show on the screen 435 00:24:24.962 --> 00:24:26.662 The top is 436 00:24:28.322 --> 00:24:30.702 what will show on the client's screen 437 00:24:30.703 --> 00:24:33.002 and the second like this 438 00:24:33.003 --> 00:24:35.962 The one below is the server 439 00:24:35.962 --> 00:24:38.281 From the server point of view, how would it look 440 00:24:38.282 --> 00:24:42.921 From the server, since the server has all player control 441 00:24:42.921 --> 00:24:46.082 Right? It has all player control 442 00:24:46.082 --> 00:24:48.662 so this problem will not happen there 443 00:24:49.502 --> 00:24:51.362 But from the client point of view 444 00:24:52.702 --> 00:24:55.662 Do I have player controller? 445 00:24:55.662 --> 00:24:58.281 I have mine but what about the other one's? 446 00:24:58.282 --> 00:25:01.821 No, it only has it's own player control 447 00:25:01.822 --> 00:25:03.241 So the other one 448 00:25:03.242 --> 00:25:05.061 Here, this SimulatedProxy 449 00:25:05.061 --> 00:25:07.840 character, the other one 450 00:25:07.841 --> 00:25:09.860 Not mine 451 00:25:09.860 --> 00:25:12.742 Does this one have player controller? 452 00:25:12.742 --> 00:25:14.882 On the client window, no 453 00:25:16.242 --> 00:25:17.822 Do you get it? 454 00:25:17.823 --> 00:25:20.261 I have player control over my character 455 00:25:20.261 --> 00:25:23.240 but for the other one 456 00:25:23.241 --> 00:25:26.300 is there player controller on the client's window? No 457 00:25:26.301 --> 00:25:28.760 Only the server has all player control 458 00:25:28.760 --> 00:25:31.960 the client only has its own player controller 459 00:25:31.961 --> 00:25:36.040 Then for this character which is a SimulatedProxy 460 00:25:36.040 --> 00:25:38.522 can there be a mainUI? 461 00:25:38.522 --> 00:25:41.162 No because there is no player controller 462 00:25:41.162 --> 00:25:44.381 but from our code logic 463 00:25:45.342 --> 00:25:48.582 when doing MulticastRPC 464 00:25:48.583 --> 00:25:50.281 It says attach pistol 465 00:25:50.281 --> 00:25:53.622 Up to here, it doesn't matter 466 00:25:53.622 --> 00:25:57.642 but here, it wants to call mainUI but 467 00:25:57.642 --> 00:26:00.681 mainUI is only made when there is player controller 468 00:26:01.422 --> 00:26:03.542 Right, but the counterpart 469 00:26:04.221 --> 00:26:07.120 Can there be a mainUI or no? 470 00:26:07.451 --> 00:26:08.451 No 471 00:26:09.031 --> 00:26:12.151 Why? Because there's no player controller 472 00:26:12.151 --> 00:26:17.022 So this attach pistol part 473 00:26:17.022 --> 00:26:19.882 can have a mainUI only when? 474 00:26:21.321 --> 00:26:25.282 When I'm controlling 475 00:26:25.282 --> 00:26:28.422 that is, when there is a player controller 476 00:26:28.702 --> 00:26:34.022 When there is player controller 477 00:26:34.022 --> 00:26:37.161 Because only then, mainUI can be made 478 00:26:37.161 --> 00:26:38.781 Using network terms 479 00:26:40.601 --> 00:26:41.601 autonomous 480 00:26:43.960 --> 00:26:47.980 Only when it is autonomous proxy 481 00:26:50.522 --> 00:26:51.362 it is possible 482 00:26:52.722 --> 00:26:54.122 Do you get it? 483 00:26:54.122 --> 00:27:00.400 So we need to test calling this mainUI 484 00:27:00.400 --> 00:27:01.300 What that is is 485 00:27:01.300 --> 00:27:06.441 if autonomous proxy, when I'm controlling 486 00:27:06.441 --> 00:27:10.160 This ultimately means is locally controlled 487 00:27:10.161 --> 00:27:13.211 Internally, when i'm the one locally controlling 488 00:27:13.211 --> 00:27:14.120 That's what if is for 489 00:27:14.120 --> 00:27:18.021 And when there is mainUI 490 00:27:18.021 --> 00:27:23.160 we'll call this 491 00:27:26.281 --> 00:27:30.041 Let's build 492 00:27:33.020 --> 00:27:35.480 and play 493 00:27:37.960 --> 00:27:40.660 Server window 494 00:27:40.661 --> 00:27:42.860 and a client window 495 00:27:42.860 --> 00:27:43.860 Let's see how it goes 496 00:27:43.860 --> 00:27:45.921 From the server, it takes a pistol 497 00:27:45.922 --> 00:27:49.881 On the client, it doesn't 498 00:27:49.882 --> 00:27:52.521 but let's see here 499 00:27:52.522 --> 00:27:54.701 Going closer 500 00:27:54.701 --> 00:27:58.240 on the client window 501 00:27:58.240 --> 00:28:02.960 you can see that the server character has the pistol in its hand 502 00:28:02.961 --> 00:28:06.760 Here, the server animation shows the animation too 503 00:28:06.760 --> 00:28:09.662 but the client just shows 504 00:28:09.662 --> 00:28:13.542 the pistol attached and the animation isn't synced 505 00:28:13.542 --> 00:28:18.080 So attach pistol is working properly 506 00:28:18.080 --> 00:28:22.562 but the animation isn't being synced 507 00:28:22.562 --> 00:28:25.202 Let's solve that 508 00:28:29.320 --> 00:28:35.180 Let's see how we sync animation 509 00:28:36.280 --> 00:28:40.640 On netpscharacter.cpp, bHasPistol 510 00:28:40.641 --> 00:28:43.680 it changes the pistol posession 511 00:28:43.681 --> 00:28:48.080 and puts this value to sync animation 512 00:28:48.081 --> 00:28:50.020 But look here 513 00:28:50.020 --> 00:28:54.081 ServerRPC function must be performed only where? 514 00:28:54.082 --> 00:28:55.582 Only in the server 515 00:28:56.022 --> 00:28:59.522 It's a code that's only performed in the server 516 00:29:00.361 --> 00:29:03.680 So it was true in server 517 00:29:03.681 --> 00:29:08.060 There's no way for the client to receive that this value is true 518 00:29:08.061 --> 00:29:12.400 So this value needs to by synced 519 00:29:12.400 --> 00:29:16.081 using property replication 520 00:29:16.601 --> 00:29:21.280 Let's go to bHasPistol implementation 521 00:29:21.281 --> 00:29:25.020 On netpscharacter.h bHasPistol is declared 522 00:29:25.020 --> 00:29:28.370 We'll add this option so that this part is 523 00:29:28.370 --> 00:29:30.201 synced on network 524 00:29:30.201 --> 00:29:34.181 u property, replicated 525 00:29:37.102 --> 00:29:39.452 We did this when we were doing property replication 526 00:29:39.452 --> 00:29:42.202 Then you'll know that 527 00:29:42.202 --> 00:29:45.120 to do this, the cpp file needs 528 00:29:45.121 --> 00:29:49.240 a function that starts with get lifetime 529 00:29:49.240 --> 00:29:55.360 void ANetTPSCharacter is already implemented 530 00:29:55.360 --> 00:30:02.961 GetLifetimeReplicatedProps function 531 00:30:02.962 --> 00:30:06.541 This function needs to be definedd 532 00:30:06.541 --> 00:30:11.720 Super, GetLifetimeReplicatedProps 533 00:30:11.720 --> 00:30:16.222 Call this and you need to do what? 534 00:30:16.222 --> 00:30:18.700 Register. Do 535 00:30:20.360 --> 00:30:22.340 REPLIFETIME 536 00:30:23.422 --> 00:30:27.623 and show the source. What from ANetTPSCharacter? 537 00:30:27.623 --> 00:30:32.080 Sync bHasPistol 538 00:30:34.040 --> 00:30:39.043 And this one has a red line, so on the very top 539 00:30:39.043 --> 00:30:41.083 we need to add include 540 00:30:42.401 --> 00:30:48.581 We have to put include the unreal network.h under net folder 541 00:30:50.401 --> 00:30:53.820 Let's build 542 00:30:56.240 --> 00:30:59.201 and see 543 00:31:01.763 --> 00:31:05.183 Just now, it was attached but the animation didn't show 544 00:31:05.183 --> 00:31:09.023 but now, both on the server and the client 545 00:31:09.023 --> 00:31:11.323 Look at the server screen 546 00:31:17.143 --> 00:31:20.383 The animation is showing 547 00:31:20.383 --> 00:31:21.903 and on the client screen as well 548 00:31:21.903 --> 00:31:24.063 the animation is playing properly 549 00:31:26.423 --> 00:31:28.883 Great 550 00:31:28.883 --> 00:31:30.863 Moving with the pistol 551 00:31:30.863 --> 00:31:35.461 the animation all works properly 552 00:31:38.660 --> 00:31:41.406 This was on take pistol 553 00:31:41.886 --> 00:31:44.520 Release pistol 554 00:31:47.263 --> 00:31:48.843 Next is release pistol 555 00:31:49.600 --> 00:31:52.950 For release pistol, similar to take pistol 556 00:31:52.950 --> 00:31:55.123 we will use RPC to 557 00:31:55.123 --> 00:31:58.183 sync on network 558 00:32:00.023 --> 00:32:03.363 As I mentioned, take pistol 559 00:32:03.363 --> 00:32:06.040 follows this flow 560 00:32:06.041 --> 00:32:08.100 On release pistol as well 561 00:32:08.100 --> 00:32:09.750 instead of TakePistol input 562 00:32:09.750 --> 00:32:12.600 a ReleasePistol input will come in 563 00:32:12.600 --> 00:32:17.361 and with the input it will request to server with server RPC 564 00:32:17.362 --> 00:32:22.081 Then the server will work on the owner setting 565 00:32:22.082 --> 00:32:24.261 and tell the client to put the pistol down 566 00:32:24.261 --> 00:32:27.241 by sending another request 567 00:32:31.061 --> 00:32:36.401 Then let's make that following that flow 568 00:32:36.423 --> 00:32:38.303 On Visual Studio 569 00:32:39.301 --> 00:32:42.580 go to NetTPSCharacter header file 570 00:32:43.920 --> 00:32:48.860 On the very bottom, this was take pistol 571 00:32:52.420 --> 00:32:56.200 and now we're going to add release pistol down here 572 00:32:57.940 --> 00:33:02.241 UFUNCTION, we'll make the same thing 573 00:33:05.040 --> 00:33:11.603 UFUNCTION, void ServerRPC_ and this time 574 00:33:11.603 --> 00:33:15.363 ReleasePistol 575 00:33:18.501 --> 00:33:22.280 It's the same as take pistol 576 00:33:22.280 --> 00:33:27.321 On release pistol as well, I'll add implementation 577 00:33:31.641 --> 00:33:37.501 I'll cut ServerRPC ReleasePistol 578 00:33:37.501 --> 00:33:41.800 and put it under the ReleasePistol function 579 00:33:45.100 --> 00:33:51.460 just to make it easier to work with 580 00:33:56.303 --> 00:34:00.703 If on this ReleasePistol, one doesn't have a pistol attached 581 00:34:00.703 --> 00:34:03.600 or reloading it, the logic is not performed 582 00:34:03.601 --> 00:34:06.520 and this is done by the client 583 00:34:06.520 --> 00:34:09.201 The server only changes data 584 00:34:09.202 --> 00:34:11.461 Where is that? It's right here 585 00:34:11.461 --> 00:34:13.861 When one has a pistol 586 00:34:13.861 --> 00:34:15.841 Where should we put this 587 00:34:15.841 --> 00:34:20.200 We'll cut this and paste it here on ServerRPC 588 00:34:23.600 --> 00:34:25.900 And on ReleasePistol 589 00:34:27.600 --> 00:34:31.880 the request will be ServerRPC ReleasePistol 590 00:34:35.000 --> 00:34:37.550 Do you get the flow? 591 00:34:37.550 --> 00:34:41.650 Here, client 592 00:34:41.650 --> 00:34:43.900 ReleasePistol is client 593 00:34:43.900 --> 00:34:45.423 On the client side 594 00:34:45.423 --> 00:34:49.323 only the input is here 595 00:34:49.323 --> 00:34:50.961 Only the input 596 00:34:50.961 --> 00:34:55.483 And then after that, from here to where? 597 00:34:55.483 --> 00:34:56.483 To the server 598 00:34:58.183 --> 00:35:01.183 It requests using server RPC 599 00:35:01.183 --> 00:35:05.240 It sends a ReleasePistol request 600 00:35:05.240 --> 00:35:10.342 Then the server receives that 601 00:35:10.343 --> 00:35:11.722 and does this part 602 00:35:11.722 --> 00:35:14.501 This is not done by the client but where? 603 00:35:14.501 --> 00:35:17.801 On the server, this logic 604 00:35:21.903 --> 00:35:24.201 And the action of releasing the pisstol 605 00:35:24.201 --> 00:35:27.501 DetachPistol is done where? 606 00:35:27.502 --> 00:35:28.902 On the client side 607 00:35:28.902 --> 00:35:30.802 So the server again 608 00:35:30.802 --> 00:35:34.181 sends a message to the client 609 00:35:36.561 --> 00:35:40.203 That's how it goes 610 00:35:40.203 --> 00:35:43.143 So we implemented this on the server 611 00:35:44.443 --> 00:35:46.623 And when the server does this 612 00:35:46.623 --> 00:35:50.120 This DetachPistol is not done in the server 613 00:35:50.121 --> 00:35:52.720 but by the client 614 00:35:52.721 --> 00:35:55.800 So to make that happen 615 00:35:55.800 --> 00:36:01.360 I'll add a code that sends NetMulticastRPC to clients 616 00:36:01.363 --> 00:36:02.983 Let's make a funciton 617 00:36:03.700 --> 00:36:08.120 Go to NetTPSCharacter header file and on the bottom 618 00:36:09.163 --> 00:36:12.443 copy this function we made on take pistol 619 00:36:12.443 --> 00:36:15.803 and paste it 620 00:36:15.803 --> 00:36:19.303 Then instead of TakePistol we'll make it 621 00:36:19.303 --> 00:36:20.560 ReleasePistol 622 00:36:25.563 --> 00:36:29.183 Then on the parameter, the code that 623 00:36:29.183 --> 00:36:32.200 detaches the pistol from the hand will perfrom 624 00:36:32.200 --> 00:36:34.450 We declared one function 625 00:36:34.450 --> 00:36:37.743 and now let's implement NetMulticastRPC 626 00:36:37.743 --> 00:36:43.103 On the cpp file, we'll add that function's implementation 627 00:36:44.543 --> 00:36:48.420 then there's ServerRPC and NetMulticastRPC 628 00:36:51.603 --> 00:36:56.023 DetachPistol goes where? 629 00:36:56.023 --> 00:36:58.841 It goes to MulticastRPC 630 00:37:00.023 --> 00:37:06.263 and then MulticastRPC call is done by ServerRPC 631 00:37:06.263 --> 00:37:09.920 Then there will be internal communication as I told you 632 00:37:10.880 --> 00:37:13.501 Then the client 633 00:37:15.563 --> 00:37:18.623 requested to the server using server RPC 634 00:37:19.703 --> 00:37:21.953 After the server has done its job 635 00:37:21.953 --> 00:37:24.900 it will use NetMulticast to request back to the clients 636 00:37:27.721 --> 00:37:32.601 and make them perfrom this code 637 00:37:32.601 --> 00:37:33.901 Do you get it? 638 00:37:35.961 --> 00:37:37.821 Great 639 00:37:37.822 --> 00:37:42.321 Then we need to put the parameter value for NetMulticastRPC 640 00:37:42.321 --> 00:37:45.361 Which one? ownedPistol 641 00:37:47.923 --> 00:37:52.663 Then the owned pistol is sent to network 642 00:37:52.663 --> 00:37:56.901 and it will receive this and the pistol will be detached 643 00:37:58.241 --> 00:37:59.741 The server will send that 644 00:37:59.741 --> 00:38:03.440 and reset all owner settings 645 00:38:07.823 --> 00:38:08.823 Great 646 00:38:08.823 --> 00:38:12.223 Again, if we play this it will crash 647 00:38:12.223 --> 00:38:13.203 Why? 648 00:38:13.203 --> 00:38:18.561 Because again on DetachPistol, it calls ShowCrosshair 649 00:38:18.561 --> 00:38:24.120 On mainUI, it will be there for the client itself 650 00:38:24.121 --> 00:38:28.800 but it also shows to other characters' screens 651 00:38:28.801 --> 00:38:31.220 That character has mainUI or no? 652 00:38:31.220 --> 00:38:36.100 It hasn't, why? Because it is made only under the condition that player controller exists 653 00:38:36.101 --> 00:38:40.080 So here, we make it not happen when there's no mainUI 654 00:38:40.080 --> 00:38:45.323 if IsLocallyControlled 655 00:38:45.323 --> 00:38:48.283 and only when there's a mainUI character 656 00:38:50.041 --> 00:38:54.460 we need to change this part so that it will be performed only in that case 657 00:38:54.460 --> 00:38:57.481 This is the same as AttachPistol 658 00:38:58.763 --> 00:39:00.743 Let's build 659 00:39:07.481 --> 00:39:11.531 Then let's run the server 660 00:39:11.531 --> 00:39:13.141 and a client 661 00:39:14.601 --> 00:39:20.200 Take a pistol, it works, and let me release it with Z 662 00:39:24.321 --> 00:39:28.280 Then there's another error, Null Point Exception 663 00:39:28.280 --> 00:39:34.083 There's an error on the character's 227th line of ReleasePistol 664 00:39:34.083 --> 00:39:35.743 What is it? 665 00:39:37.103 --> 00:39:39.521 I didn't put pistolActor 666 00:39:39.521 --> 00:39:42.321 put just copy pasted DetachPistol 667 00:39:42.322 --> 00:39:44.201 so it says ownedPistol 668 00:39:44.201 --> 00:39:48.560 We'll put pistolActor here 669 00:39:48.561 --> 00:39:51.011 Why? Because if it says ownedPistol 670 00:39:51.011 --> 00:39:53.480 this one needs to release the one it got from the server 671 00:39:53.480 --> 00:39:57.680 so it might try to release the ownedPistol which it doesn't even posess 672 00:39:57.681 --> 00:39:59.930 which might cause an error 673 00:39:59.930 --> 00:40:05.760 So we need to make it detach the data it got from here 674 00:40:05.760 --> 00:40:08.710 Only then this value will be processed properly 675 00:40:08.710 --> 00:40:09.741 Let's build again 676 00:40:21.523 --> 00:40:25.023 and play with a client added 677 00:40:25.023 --> 00:40:28.283 F, take pistol 678 00:40:28.284 --> 00:40:30.063 Z, release 679 00:40:30.063 --> 00:40:32.161 You can see the pistol falls to the ground 680 00:40:32.161 --> 00:40:37.283 Again, F, maybe release it here 681 00:40:37.283 --> 00:40:40.543 I released it here on a hill 682 00:40:41.481 --> 00:40:44.441 Here's the pistol 683 00:40:44.442 --> 00:40:47.841 From the client side, let's see if the pistol is indeed there 684 00:40:47.841 --> 00:40:49.340 Aha, it's here 685 00:40:51.583 --> 00:40:57.223 Let me try the same thing on the client side 686 00:40:57.224 --> 00:41:00.443 Put it down here 687 00:41:00.443 --> 00:41:03.920 It's being synced well 688 00:41:08.501 --> 00:41:10.761 But there's something I want to show you 689 00:41:12.423 --> 00:41:16.523 Let's see the pistol placement on the client's screen and the server screen 690 00:41:16.523 --> 00:41:20.321 On the client's screen, the one on the left 691 00:41:20.321 --> 00:41:23.480 It shows that the pistol is here 692 00:41:25.163 --> 00:41:28.163 And let's see the right screen 693 00:41:28.163 --> 00:41:30.841 On the server screen, where is the pistol? 694 00:41:34.260 --> 00:41:36.461 It's at a different spot 695 00:41:38.203 --> 00:41:40.003 So in the server, the pistol is here 696 00:41:40.003 --> 00:41:41.543 but it's somewhere different for the client 697 00:41:41.543 --> 00:41:43.440 This is an error 698 00:41:44.443 --> 00:41:47.883 So even when the server wants to take the pistol 699 00:41:47.883 --> 00:41:49.033 when performing that logic 700 00:41:49.033 --> 00:41:50.880 it's here for the client so even if it tries to take it 701 00:41:50.880 --> 00:41:53.130 if it's somewhere random 702 00:41:53.130 --> 00:41:55.220 then it can't take it 703 00:41:55.221 --> 00:41:57.640 because on the server, it says that it's here 704 00:41:57.640 --> 00:42:01.800 The location data isn't being synced 705 00:42:01.800 --> 00:42:04.481 Then what should we do 706 00:42:04.482 --> 00:42:08.321 We can activate Actor Replication that we learned 707 00:42:08.321 --> 00:42:11.421 There's this BP Pistol 708 00:42:11.421 --> 00:42:14.943 There's BP Pistol on NetTPS Blueprint 709 00:42:14.943 --> 00:42:16.223 Open this 710 00:42:17.401 --> 00:42:22.280 and let me search Replicate on BP Pistol's detail window 711 00:42:22.281 --> 00:42:25.380 Search Replicate 712 00:42:25.380 --> 00:42:27.230 and you'll see Replicate Movement 713 00:42:27.230 --> 00:42:28.860 and Replicate 714 00:42:28.860 --> 00:42:31.410 These aren't activated 715 00:42:31.410 --> 00:42:33.400 so it is not being synced 716 00:42:33.401 --> 00:42:35.760 So check on Replicate option 717 00:42:35.760 --> 00:42:38.704 and Replicate Movement as well 718 00:42:38.704 --> 00:42:42.004 and then the values on movements, within Unreal Engine 719 00:42:42.004 --> 00:42:43.104 will be synced 720 00:42:45.384 --> 00:42:49.104 If you say that you'll replicate, network sync 721 00:42:49.104 --> 00:42:52.040 on Blueprint, it automatically does that 722 00:42:52.040 --> 00:42:56.361 'Then on C++, not only that but 723 00:42:56.362 --> 00:42:57.862 property value needs to be synced 724 00:42:57.862 --> 00:43:02.024 and Get Lifetime Replicated, all these need to be done too' 725 00:43:02.024 --> 00:43:02.664 Right 726 00:43:04.264 --> 00:43:06.164 These parts too 727 00:43:06.164 --> 00:43:08.884 But on Blueprint, that part ins't needed 728 00:43:08.884 --> 00:43:10.860 It's simpler on Blueprint 729 00:43:10.861 --> 00:43:14.280 But when making these network codes and logic 730 00:43:14.280 --> 00:43:17.361 it's more efficient to work on C++ 731 00:43:17.361 --> 00:43:19.811 It helps with management too 732 00:43:19.811 --> 00:43:22.900 but Blueprint has an easier structure 733 00:43:24.324 --> 00:43:26.544 Of course, when working on RPC and such 734 00:43:26.544 --> 00:43:28.024 if you keep going back and forth with Blueprint 735 00:43:28.024 --> 00:43:30.760 you can get very confused with the logic 736 00:43:30.760 --> 00:43:35.081 So usually, C++ does all of the network 737 00:43:36.241 --> 00:43:40.001 But here, the pistol ins't being synced 738 00:43:40.002 --> 00:43:43.721 so I just used these two Replicate options in the detail window 739 00:43:43.721 --> 00:43:47.860 to sync this pistol actor 740 00:43:49.160 --> 00:43:52.080 Let's go back and play 741 00:43:55.144 --> 00:43:59.344 Go, and Z, released 742 00:43:59.344 --> 00:44:03.520 Then for the server, it's on the ground 743 00:44:03.520 --> 00:44:05.320 From the client as well 744 00:44:05.320 --> 00:44:07.480 it's on the ground 745 00:44:07.481 --> 00:44:11.660 F, let's drop it somewhere else 746 00:44:11.660 --> 00:44:15.301 and the two on network 747 00:44:15.302 --> 00:44:18.142 are being synced 748 00:44:18.142 --> 00:44:20.441 The same location 749 00:44:20.441 --> 00:44:24.160 You can test this further 750 00:44:25.184 --> 00:44:28.964 and Blueprint can very simply 751 00:44:28.964 --> 00:44:30.864 sync movement 752 00:44:30.864 --> 00:44:33.561 and location value 753 00:44:33.561 --> 00:44:35.761 by activating Replicate options 754 00:44:35.761 --> 00:44:38.841 on network 755 00:44:38.842 --> 00:44:41.801 That will be it 756 00:44:41.801 --> 00:44:44.721 This was release pistol 757 00:44:46.481 --> 00:44:49.240 Let's summarize what we've learned in this unit 758 00:44:50.592 --> 00:44:51.592 Take pistol RPC communication 759 00:44:51.593 --> 00:44:52.484 User only performs input and the logic is performed in the server using server RPC 760 00:44:52.485 --> 00:44:53.364 NetMulticast is used together to perform animation and visualization on all clients 761 00:44:53.365 --> 00:44:56.124 UI It must work only on clients Needs a logic to separate UI 762 00:44:56.125 --> 00:44:57.349 Animation Uses property replication 763 00:44:57.349 --> 00:44:58.709 Release pistol RPC communication 764 00:44:58.710 --> 00:45:01.729 Requests to server to release pistol using server RPC Uses NetMulticast RPC to send result to all clients 765 00:45:01.729 --> 00:45:02.729 The End