WEBVTT 1 00:00:23.680 --> 00:00:25.600 Hello, this is Youngho Lee 2 00:00:25.600 --> 00:00:29.360 In this unit, we will learn firing and reloading 3 00:00:29.360 --> 00:00:31.840 Similar to take pistol and release pistol 4 00:00:31.840 --> 00:00:34.800 we will use RPC 5 00:00:34.800 --> 00:00:38.080 and we'll see how what the server performs 6 00:00:38.080 --> 00:00:40.560 and what client performs is divided 7 00:00:40.560 --> 00:00:42.480 Fire using RPC 8 00:00:45.040 --> 00:00:46.680 First is fire 9 00:00:46.680 --> 00:00:48.639 Fire on network 10 00:00:48.639 --> 00:00:52.760 similar to take pistol and release pistol that we did 11 00:00:52.760 --> 00:00:55.680 uses RPC communication 12 00:00:55.680 --> 00:00:57.700 The logic is like this 13 00:00:59.520 --> 00:01:01.680 Here, there's a client 14 00:01:01.680 --> 00:01:04.579 and the client receives a fire input 15 00:01:05.599 --> 00:01:07.279 It gets this input 16 00:01:07.279 --> 00:01:10.240 and the client, with this input 17 00:01:10.240 --> 00:01:14.280 requests the server 18 00:01:15.920 --> 00:01:18.799 that it wants to fire 19 00:01:18.799 --> 00:01:21.479 with RPC, a server RPC 20 00:01:24.819 --> 00:01:26.540 to the server 21 00:01:27.420 --> 00:01:30.879 Then the server receives this server RPC 22 00:01:30.879 --> 00:01:33.059 and performs fire logic 23 00:01:33.959 --> 00:01:36.959 Like line trace and fire 24 00:01:36.959 --> 00:01:41.160 It performs fire logic and the result 25 00:01:41.160 --> 00:01:44.160 is sent to the client 26 00:01:44.160 --> 00:01:47.599 like 'hey there's this piece flying off' 27 00:01:47.599 --> 00:01:51.720 'so update the UI', these requests are made 28 00:01:51.720 --> 00:02:00.099 That will be the client or NetMulticast RPC 29 00:02:02.239 --> 00:02:06.199 In this format, the request is sent to clients 30 00:02:06.199 --> 00:02:10.360 Then, the client or the clients of Multicast 31 00:02:10.360 --> 00:02:13.639 will perform according to this RPC request 32 00:02:13.639 --> 00:02:18.279 Fire happens in this flow 33 00:02:18.279 --> 00:02:21.279 Now let's make this 34 00:02:21.279 --> 00:02:23.760 Go to Visual Studio 35 00:02:23.760 --> 00:02:30.279 and to NetTPSCharacter header file 36 00:02:30.279 --> 00:02:35.079 Let's make the fire part here on the very bottom 37 00:02:37.839 --> 00:02:41.839 When user inputs fire 38 00:02:41.839 --> 00:02:45.759 we're going to add a server RPC function 39 00:02:45.759 --> 00:02:50.259 UFunction, server as it's a server RPC 40 00:02:50.259 --> 00:02:53.039 and reliable 41 00:02:53.039 --> 00:02:59.440 Then Void ServerRPC_Fire 42 00:02:59.440 --> 00:03:03.080 This means requesting fire to the server 43 00:03:03.080 --> 00:03:06.520 Let's implement this function 44 00:03:06.520 --> 00:03:10.839 ServerRPC Fire Implementation function's implementation 45 00:03:10.839 --> 00:03:15.800 will be move to under the fire function 46 00:03:15.800 --> 00:03:17.460 to make it easier to work with 47 00:03:18.960 --> 00:03:24.839 Then, there needs a part where 48 00:03:24.839 --> 00:03:28.559 client or NetMulticast RPC is called within here 49 00:03:28.559 --> 00:03:32.080 Like I mentioned using the diagram 50 00:03:32.080 --> 00:03:36.320 the part where the clients receives input 51 00:03:36.320 --> 00:03:40.919 and where it requests server RPC 52 00:03:40.919 --> 00:03:42.580 must be divided 53 00:03:44.520 --> 00:03:47.270 So when Fire function is called 54 00:03:47.270 --> 00:03:49.679 that's when the user presses on the fire button 55 00:03:49.679 --> 00:03:53.399 When that happens, if it's not holding a pistol 56 00:03:53.399 --> 00:03:55.800 or if there's no bullet left 57 00:03:55.800 --> 00:03:58.320 or if it's reloading 58 00:03:58.320 --> 00:04:00.880 Unless these cases, the below is performed 59 00:04:00.880 --> 00:04:03.679 If it's holding a pistol, the following will be performed 60 00:04:03.679 --> 00:04:07.080 Does this fire part happen on the client side? 61 00:04:07.080 --> 00:04:11.000 No. It will happen in the server 62 00:04:11.000 --> 00:04:15.880 Let's use server RPC to do that 63 00:04:15.880 --> 00:04:20.199 Call ServerRPC Fire 64 00:04:20.199 --> 00:04:24.400 and where will these that are the actual pistol firing go 65 00:04:25.119 --> 00:04:28.039 They should move to the client side 66 00:04:30.880 --> 00:04:34.340 Let's first move it to the ServerRPC part 67 00:04:35.960 --> 00:04:41.279 When fire button is pressed, this happens 68 00:04:41.279 --> 00:04:45.279 and then it requests the server to perform fire 69 00:04:45.279 --> 00:04:48.519 Then, fire is performed using server RPC 70 00:04:48.519 --> 00:04:53.519 The fire logic is performed in the server like this 71 00:04:53.519 --> 00:04:58.220 But showing the shot particles is related to rendering 72 00:04:58.220 --> 00:04:59.839 It's a visual aspect 73 00:04:59.839 --> 00:05:04.600 This part isn't done in the server, where does it happen? 74 00:05:04.600 --> 00:05:07.539 On the client side 75 00:05:07.539 --> 00:05:10.519 Then the UI update 76 00:05:10.519 --> 00:05:12.959 This part will also be done on the client side 77 00:05:12.959 --> 00:05:16.199 and animation will also be there 78 00:05:17.839 --> 00:05:21.480 So these need to be worked on separately 79 00:05:21.480 --> 00:05:23.080 To work on this fire action 80 00:05:23.080 --> 00:05:25.519 separately from server and client 81 00:05:25.519 --> 00:05:27.760 let's make the part that the client will do 82 00:05:27.760 --> 00:05:32.399 using NetMulticast RPC 83 00:05:32.399 --> 00:05:33.559 Go to header file 84 00:05:33.559 --> 00:05:38.239 To NetTPSCharacter's header file 85 00:05:38.239 --> 00:05:41.600 Here, to use a NetMulticast RPC 86 00:05:41.600 --> 00:05:49.720 u Function NetMulticast, then you can say reliable 87 00:05:49.720 --> 00:05:52.399 but I'll put unreliable here 88 00:05:52.399 --> 00:05:55.480 The reason of putting unreliable is 89 00:05:55.480 --> 00:05:56.679 This part here 90 00:05:56.679 --> 00:05:59.480 The core logic of fire 91 00:05:59.480 --> 00:06:02.119 will all happen in the server 92 00:06:02.119 --> 00:06:03.959 Right? The demage process 93 00:06:03.959 --> 00:06:07.959 and HP decrement will happen here 94 00:06:07.959 --> 00:06:11.600 But particle effects and such 95 00:06:11.600 --> 00:06:14.640 will have to happen in the client 96 00:06:14.660 --> 00:06:19.600 But is particle effect necessary when a shot is fired? 97 00:06:19.600 --> 00:06:20.480 It isn't 98 00:06:20.480 --> 00:06:23.399 It won't matter if this doesn't happen once or twice 99 00:06:23.399 --> 00:06:27.040 Even if it's omitted, the data itself isn't being deleted 100 00:06:27.040 --> 00:06:29.279 so the user's data like HP 101 00:06:29.279 --> 00:06:32.899 will be processed in the server so it will be maintained 102 00:06:32.920 --> 00:06:35.370 but the effect might not happen once in a while 103 00:06:35.370 --> 00:06:37.300 depending on network circumstances 104 00:06:37.320 --> 00:06:40.160 But important parts like HP 105 00:06:40.160 --> 00:06:42.720 will be done in the server so it doesn't matter 106 00:06:42.720 --> 00:06:46.320 So the visual effects 107 00:06:46.320 --> 00:06:49.200 of fire for the client 108 00:06:49.200 --> 00:06:53.179 doesn't matter too much to be considered absolutely necessary 109 00:06:53.179 --> 00:06:55.040 so I'll put unreliable 110 00:06:55.040 --> 00:07:02.880 void Multicast RPC_Fire 111 00:07:02.880 --> 00:07:07.040 And for the parameter 112 00:07:07.040 --> 00:07:14.080 we might need information about the collision point and whether it did collide or not 113 00:07:14.080 --> 00:07:17.920 Why? Because only when it did, on the spot it did 114 00:07:17.920 --> 00:07:20.720 the particle effect must show 115 00:07:20.720 --> 00:07:23.760 So on the parameter 116 00:07:23.760 --> 00:07:26.959 we'll put bool, bHit 117 00:07:26.959 --> 00:07:32.640 and then const fHitResult 118 00:07:34.220 --> 00:07:37.679 Then hitinfo with annotation 119 00:07:37.679 --> 00:07:40.720 Then if it did collide, if true value was input 120 00:07:40.720 --> 00:07:44.919 that point will have particle effect 121 00:07:44.920 --> 00:07:47.880 and this will be performed 122 00:07:47.880 --> 00:07:51.640 Let's add implementation on Multicast RPC Fire 123 00:07:53.600 --> 00:07:57.519 I added implementation on NetTPSCharacter.cpp 124 00:07:57.519 --> 00:08:01.579 What do we want to do when it collided? 125 00:08:01.579 --> 00:08:04.559 We want particles on the collision point 126 00:08:04.559 --> 00:08:09.640 When bHit is true, this part needs to be performed 127 00:08:09.679 --> 00:08:13.880 I'll take this part and put it here 128 00:08:16.399 --> 00:08:21.549 So if bHit value is true 129 00:08:21.549 --> 00:08:23.920 particles will show 130 00:08:25.079 --> 00:08:29.320 Next, for bulletCount that removes bullets 131 00:08:29.320 --> 00:08:31.420 the data is changed in the server 132 00:08:31.420 --> 00:08:33.479 so the client doesn't need to care about this 133 00:08:33.480 --> 00:08:36.080 But this part is needed 134 00:08:36.080 --> 00:08:39.279 Updating the mainUI is needed 135 00:08:39.279 --> 00:08:43.180 So we'll take this part 136 00:08:44.900 --> 00:08:47.200 and put it here 137 00:08:47.200 --> 00:08:52.300 I just cut it out 138 00:08:52.320 --> 00:08:56.070 On the server RPC 139 00:08:56.070 --> 00:08:59.339 does it need this part where it shows the particle? 140 00:08:59.359 --> 00:09:03.680 The server doesn't, it just need to make the logic 141 00:09:03.680 --> 00:09:07.000 It just needs to check if it did or didn't collide 142 00:09:07.000 --> 00:09:10.750 and set the data by proving the logic when it did 143 00:09:10.750 --> 00:09:12.240 That's the server's role 144 00:09:12.240 --> 00:09:16.929 Then the effect of showing something on the screen 145 00:09:16.929 --> 00:09:20.959 and UI update, these need to be done in the client 146 00:09:20.960 --> 00:09:23.410 Before we take the animation part 147 00:09:23.410 --> 00:09:26.300 the main UI also had a problem 148 00:09:26.300 --> 00:09:29.080 before when we did take and release pistol 149 00:09:29.080 --> 00:09:32.230 Other characters 150 00:09:32.230 --> 00:09:36.000 that is, clients without player controller 151 00:09:36.000 --> 00:09:38.000 do not make mainUI 152 00:09:38.039 --> 00:09:41.840 In that case, mainUI is null 153 00:09:41.840 --> 00:09:44.240 So only when there is a mainUI 154 00:09:44.240 --> 00:09:46.699 this must be performed 155 00:09:46.699 --> 00:09:52.919 if mainUI, for it to be performed only when 156 00:09:55.159 --> 00:09:57.039 there is a mainUI 157 00:09:57.039 --> 00:09:59.599 Lastly, on Multicast RPC fire 158 00:09:59.599 --> 00:10:02.679 this is called on clients 159 00:10:02.679 --> 00:10:05.239 So animation 160 00:10:06.200 --> 00:10:10.080 must also be called on the client and not the server 161 00:10:10.080 --> 00:10:13.239 Let's cut that out and bring it down here 162 00:10:13.239 --> 00:10:17.479 Then the server simply checks the fire logic 163 00:10:17.479 --> 00:10:19.039 and makes data 164 00:10:19.039 --> 00:10:22.039 It removes bullets 165 00:10:22.039 --> 00:10:25.159 Then its job is done 166 00:10:25.159 --> 00:10:28.900 so it sends visualization request to the 167 00:10:28.900 --> 00:10:31.400 client side 168 00:10:31.400 --> 00:10:35.700 Then this Multicast RPC fire could be called from the server 169 00:10:35.719 --> 00:10:42.239 From server RPC, Multicast RPC_fire 170 00:10:42.239 --> 00:10:44.000 Let's call it 171 00:10:44.000 --> 00:10:46.799 Here, bHit information needs to be included 172 00:10:46.799 --> 00:10:49.919 and hitinfo as well 173 00:10:49.919 --> 00:10:52.719 so that the data is sent on network 174 00:10:52.719 --> 00:10:56.559 and the value delivered by parameter is used 175 00:10:56.559 --> 00:11:00.039 to visualize these things 176 00:11:09.200 --> 00:11:11.760 Great. When a shot is fire, the mainUI 177 00:11:11.760 --> 00:11:17.340 does PopBullet and updates the number of bullets left of bulletCount 178 00:11:17.340 --> 00:11:18.880 That's this part here 179 00:11:18.880 --> 00:11:21.599 I'll build here 180 00:11:21.599 --> 00:11:24.640 Let's see how it looks 181 00:11:24.640 --> 00:11:29.280 Play, and I'll open server 182 00:11:29.280 --> 00:11:31.239 and a client 183 00:11:31.239 --> 00:11:37.440 Let's fire a shot 184 00:11:37.440 --> 00:11:40.599 Let me do it from the client window 185 00:11:40.599 --> 00:11:41.859 Take the pistol 186 00:11:43.242 --> 00:11:44.242 I'll shoot to the wall 187 00:11:44.799 --> 00:11:46.559 Pew pew 188 00:11:47.359 --> 00:11:50.080 Can you spot the problem? 189 00:11:50.080 --> 00:11:53.640 The animation is working both on the client 190 00:11:53.640 --> 00:11:56.119 and on the server 191 00:11:56.119 --> 00:11:58.400 Let me shoot to the ground 192 00:11:58.400 --> 00:12:02.060 The effect is also working well on both sides 193 00:12:02.960 --> 00:12:05.599 But one problem 194 00:12:05.599 --> 00:12:08.559 The UI isn't being upated 195 00:12:08.559 --> 00:12:12.679 Here, the bullet isn't being updated 196 00:12:12.679 --> 00:12:15.479 on neither windows 197 00:12:15.479 --> 00:12:17.880 Let's try on the server window 198 00:12:17.880 --> 00:12:19.840 Server takes the pistol 199 00:12:19.840 --> 00:12:21.760 Pew pew 200 00:12:21.760 --> 00:12:27.359 On the server, the UI is updated 201 00:12:27.359 --> 00:12:30.939 But it isn't on the client's window 202 00:12:30.939 --> 00:12:34.400 It's because of this part 203 00:12:34.400 --> 00:12:37.760 Let's go back to the logic 204 00:12:37.760 --> 00:12:41.340 Looking at the fire logic of ours 205 00:12:42.000 --> 00:12:47.039 the server performed the fire logic and changed the data 206 00:12:47.039 --> 00:12:50.320 The client updated the screen with that data 207 00:12:50.320 --> 00:12:53.000 and rendered for visualization 208 00:12:53.000 --> 00:12:55.280 Then when there is a mainUI 209 00:12:55.280 --> 00:13:01.039 it is set to pop bullet to match the current bulletCount when updating the UI 210 00:13:01.039 --> 00:13:03.880 The bulletCount was decreased 211 00:13:03.880 --> 00:13:09.159 and the data was sent to the client 212 00:13:09.159 --> 00:13:11.239 using RPC 213 00:13:11.239 --> 00:13:15.400 But the bulletCount wasn't properly applied 214 00:13:15.400 --> 00:13:18.200 so bullets weren't popped 215 00:13:18.200 --> 00:13:21.819 Then why did it work on the server 216 00:13:21.819 --> 00:13:23.269 It sent a server RPC 217 00:13:23.269 --> 00:13:25.879 Then the server RPC will do this 218 00:13:25.880 --> 00:13:27.680 Then it sends a client 219 00:13:27.680 --> 00:13:30.020 But how is the server RPC? 220 00:13:30.020 --> 00:13:31.640 It's a server and a client 221 00:13:31.640 --> 00:13:35.159 So from its point of view, I decreased it 222 00:13:35.159 --> 00:13:37.799 on the server window 223 00:13:37.799 --> 00:13:41.359 so even if its own RPC is called, it properly has the decreased count 224 00:13:41.359 --> 00:13:43.719 But on the other client's screen 225 00:13:43.719 --> 00:13:47.599 even if it was decreased on the server it wasn't sent to the client 226 00:13:47.599 --> 00:13:51.279 Let's get back to the screen and shoot on the server 227 00:13:51.280 --> 00:13:55.359 You can see that the server is being updated 228 00:13:55.359 --> 00:13:58.520 This part own here is being updated 229 00:13:58.520 --> 00:14:01.640 But on the client window it isn't 230 00:14:01.640 --> 00:14:05.200 Why? Because this is using a server RPC 231 00:14:05.200 --> 00:14:10.599 and this guy is a server and a client at the same time 232 00:14:10.599 --> 00:14:14.320 So it decreased its own bulletCount 233 00:14:14.320 --> 00:14:17.520 then with NetMulticast RPC 234 00:14:17.520 --> 00:14:19.780 it was sent to call clients. Then what happens? 235 00:14:19.780 --> 00:14:23.320 The server will send it to this one an also to the other window 236 00:14:23.320 --> 00:14:26.920 The message will be set to here as well since it's a Multicast RPC 237 00:14:26.920 --> 00:14:28.839 Then let's see 238 00:14:30.679 --> 00:14:33.880 From here, the bulletCount decreased 239 00:14:33.880 --> 00:14:36.320 because this bulletCount was sent back to me 240 00:14:36.320 --> 00:14:40.720 I know this bulletCount data 241 00:14:40.720 --> 00:14:43.880 That's why it decreased properly 242 00:14:43.880 --> 00:14:48.679 On the other hand, the updated data was sent to this guy here 243 00:14:48.719 --> 00:14:52.079 but this one isn't being updated 244 00:14:52.080 --> 00:14:56.359 That means the bulletCount data wasn't sent properly 245 00:14:56.359 --> 00:14:59.919 It was sent here but not here 246 00:14:59.919 --> 00:15:04.080 Let's look at the bulletCount on our code 247 00:15:04.080 --> 00:15:06.520 We're at the declaration of the bulletCount 248 00:15:06.520 --> 00:15:09.719 We're at NetTPSCharacter.h's declaration 249 00:15:09.719 --> 00:15:14.479 It isn't being synced at all on network 250 00:15:14.479 --> 00:15:16.760 We didn't put such option in 251 00:15:16.760 --> 00:15:20.440 So this needs property replication 252 00:15:20.440 --> 00:15:23.000 That way, when value is changed on network 253 00:15:23.000 --> 00:15:26.360 the server can automatically sync it 254 00:15:26.360 --> 00:15:28.320 So here, on the number of bullets left 255 00:15:28.320 --> 00:15:35.040 I'll put UPROPERTY.replicated 256 00:15:36.000 --> 00:15:40.000 I just declared that I'll sync on network 257 00:15:40.000 --> 00:15:41.559 Is this enough? 258 00:15:41.560 --> 00:15:42.560 No 259 00:15:42.560 --> 00:15:45.910 Go to cpp file 260 00:15:45.910 --> 00:15:50.239 and on the GetLifetimeReplicatedProps function on the very bottom 261 00:15:50.239 --> 00:15:52.119 we need to define it 262 00:15:52.119 --> 00:15:53.919 We need to add implementation 263 00:15:53.919 --> 00:15:54.869 Which one? 264 00:15:54.869 --> 00:15:56.799 Sync the bulletCount 265 00:15:56.799 --> 00:15:59.599 You need to add this implementation 266 00:15:59.599 --> 00:16:05.840 That way the header can tell if it's subject to network syncing 267 00:16:05.840 --> 00:16:08.880 and then on GetLifetimeReplicatedProps 268 00:16:08.880 --> 00:16:13.880 the variable's property synchronization code will be performed 269 00:16:13.880 --> 00:16:16.380 Let's build 270 00:16:21.760 --> 00:16:25.880 Great. It's working fine on the server 271 00:16:25.880 --> 00:16:27.730 Take the pistol and shoot 272 00:16:27.730 --> 00:16:31.679 and you can see the bullet decreasing in the server 273 00:16:31.679 --> 00:16:34.440 Now, on the client window 274 00:16:34.440 --> 00:16:37.679 Just now the UI didn't update 275 00:16:37.679 --> 00:16:39.829 Now, shooting from the client window 276 00:16:39.829 --> 00:16:42.559 it's decreasing properly 277 00:16:42.559 --> 00:16:45.960 But if we didn't work on this part here 278 00:16:45.960 --> 00:16:50.400 If on GetLifetimeReplicatedProps 279 00:16:50.400 --> 00:16:55.440 I didn't make it sync, what would happen? 280 00:16:55.440 --> 00:16:58.840 Will the bulletCount be synced on network? 281 00:16:58.840 --> 00:17:01.159 No, because it's only declared 282 00:17:01.159 --> 00:17:04.359 I annotated the sync structure 283 00:17:04.359 --> 00:17:06.099 Now looking at the screen 284 00:17:09.239 --> 00:17:14.760 The server, it's its own data so the UI will be updated 285 00:17:14.760 --> 00:17:16.260 There's no meaning in data syncing 286 00:17:16.260 --> 00:17:17.840 because it's me changing my data 287 00:17:17.840 --> 00:17:19.359 Because I'm the server and the client 288 00:17:19.359 --> 00:17:22.080 But on for the client 289 00:17:22.080 --> 00:17:24.400 it requests to the server with RPC 290 00:17:24.400 --> 00:17:27.280 and that server RPC is decreasing the bulletCount 291 00:17:27.280 --> 00:17:30.640 There's no way for the client to receive that data for now 292 00:17:30.640 --> 00:17:33.839 Is it being updated? 293 00:17:33.839 --> 00:17:35.599 It's not 294 00:17:35.599 --> 00:17:39.000 Why? Because it's not activated 295 00:17:39.000 --> 00:17:44.139 But if I activate this again 296 00:17:48.239 --> 00:17:49.339 Play 297 00:17:51.839 --> 00:17:55.520 On the server, the UI is properly updating 298 00:17:55.520 --> 00:17:58.160 It didn't work on the client just now 299 00:17:58.160 --> 00:18:01.040 Let's try on the client window 300 00:18:01.040 --> 00:18:04.040 Now, we added the implementation 301 00:18:04.040 --> 00:18:05.479 to make it sync 302 00:18:05.479 --> 00:18:09.839 so now, you can see that the UI is being updated properly 303 00:18:09.839 --> 00:18:11.760 The action taking place in this screen 304 00:18:11.760 --> 00:18:15.359 is the server performing the RPC 305 00:18:15.359 --> 00:18:19.439 and then on the client 306 00:18:19.439 --> 00:18:22.800 the bulletCount was set to be synced 307 00:18:22.800 --> 00:18:26.439 so the UI is updated 308 00:18:26.439 --> 00:18:29.199 Look at the screen 309 00:18:29.199 --> 00:18:32.620 On fire, it's not only RPC communication that happens 310 00:18:33.880 --> 00:18:34.920 What else was there? 311 00:18:34.920 --> 00:18:40.280 Property replication also happened 312 00:18:40.280 --> 00:18:41.919 Property replication 313 00:18:44.079 --> 00:18:45.479 So from that 314 00:18:45.479 --> 00:18:48.520 The client is now requesting a server RPC 315 00:18:48.520 --> 00:18:52.079 Since I wrote server RPC it looks like that's being performed here 316 00:18:52.079 --> 00:18:53.779 but here it's just requesting 317 00:18:56.439 --> 00:18:57.920 to the server 318 00:18:57.920 --> 00:19:02.699 Then the server's logic performs the server RPC 319 00:19:04.599 --> 00:19:09.959 Through the server RPC request, server code is performed 320 00:19:09.959 --> 00:19:12.040 Then what happens here 321 00:19:12.040 --> 00:19:13.580 It line traces 322 00:19:15.520 --> 00:19:19.079 and on the collision point, bHit 323 00:19:19.079 --> 00:19:23.360 With the information about the collision point, damage process is run 324 00:19:24.760 --> 00:19:28.060 Damage process 325 00:19:31.000 --> 00:19:34.520 Then after all this is done, to the client 326 00:19:34.520 --> 00:19:36.470 what does it do? 327 00:19:36.470 --> 00:19:37.399 It sends 328 00:19:40.959 --> 00:19:42.809 Send to who? 329 00:19:42.809 --> 00:19:46.640 To call clients, it sends with Multicast RPC 330 00:19:46.640 --> 00:19:49.500 Then here, Multicast RPC 331 00:19:51.643 --> 00:19:52.883 is called 332 00:19:54.800 --> 00:19:57.800 and the Multicast RPC function is performed here 333 00:19:57.800 --> 00:20:00.460 Here, particle effect 334 00:20:01.680 --> 00:20:03.239 animation 335 00:20:03.943 --> 00:20:07.683 and UI and such are being updated 336 00:20:07.983 --> 00:20:11.433 But when trying to update this UI 337 00:20:11.433 --> 00:20:15.733 the variable bulletCount 338 00:20:15.733 --> 00:20:20.152 isn't being properly updated 339 00:20:20.152 --> 00:20:24.063 The reason is because it only worked with RPC 340 00:20:24.063 --> 00:20:27.043 So how did we fix this bulletCount? 341 00:20:27.043 --> 00:20:31.743 We used property replication 342 00:20:31.743 --> 00:20:35.483 We used UPROPERTY replicated 343 00:20:35.483 --> 00:20:40.142 and then we registered bulletCount by putting DoRepLifetime 344 00:20:41.122 --> 00:20:45.382 Then the bulletCount value was automatically 345 00:20:45.383 --> 00:20:49.262 decreased in the server 346 00:20:49.262 --> 00:20:51.941 So decreasing it by 1 347 00:20:51.942 --> 00:20:55.163 synced it automatically and updated it 348 00:20:55.163 --> 00:20:57.623 Then there's one thing to think about here 349 00:20:57.623 --> 00:21:02.122 Does this have to be done with property replication? 350 00:21:02.122 --> 00:21:05.401 It may not be 351 00:21:06.823 --> 00:21:11.123 I'll annotate this instead of having it like this 352 00:21:11.123 --> 00:21:16.262 Let's say we also turn this UPROPERTY replicate option 353 00:21:16.262 --> 00:21:17.082 Then 354 00:21:17.863 --> 00:21:19.723 will there be no way to sync? 355 00:21:19.723 --> 00:21:21.663 No, there is a way 356 00:21:23.442 --> 00:21:26.821 Here on MulticastRPC 357 00:21:31.101 --> 00:21:36.062 I'll say const int32 and newBulletCount 358 00:21:37.642 --> 00:21:44.741 So we're adding this part on MulticastRPC 359 00:21:45.903 --> 00:21:46.903 on cpp 360 00:21:48.061 --> 00:21:51.861 Then, on MulticastRPC Fire 361 00:21:51.861 --> 00:21:54.921 we're handing this factor over, bulletCount 362 00:21:57.242 --> 00:22:00.042 Then this bulletCount 363 00:22:00.042 --> 00:22:04.761 will be delivered as a parameter factor on network 364 00:22:04.761 --> 00:22:05.511 Right 365 00:22:05.511 --> 00:22:07.861 Then what should we do with this value 366 00:22:07.861 --> 00:22:10.121 We assign newBulletCount 367 00:22:10.763 --> 00:22:14.303 on bulletCount 368 00:22:14.303 --> 00:22:15.453 Good? 369 00:22:15.453 --> 00:22:18.153 If we work this way 370 00:22:18.153 --> 00:22:23.641 the updated value will be sent 371 00:22:23.641 --> 00:22:26.391 Even this, 372 00:22:26.391 --> 00:22:29.521 we can also make it update only when there's a mainUI 373 00:22:29.521 --> 00:22:31.182 because it will be needed only in that case 374 00:22:36.623 --> 00:22:40.301 I'll build here and see 375 00:22:40.301 --> 00:22:43.551 Now the replicated part is gone 376 00:22:43.551 --> 00:22:45.482 I deleted the property replication 377 00:22:47.162 --> 00:22:49.842 Let's see 378 00:22:53.342 --> 00:22:57.040 The server is updating properly 379 00:22:57.040 --> 00:22:59.640 and the client as well 380 00:22:59.640 --> 00:23:03.020 The UI is being updated properly 381 00:23:04.081 --> 00:23:06.462 You can see it down here 382 00:23:08.361 --> 00:23:12.161 So this part doesn't need to be 383 00:23:12.161 --> 00:23:15.065 done with property replication only 384 00:23:15.065 --> 00:23:17.165 You can use RPC 385 00:23:17.165 --> 00:23:19.345 to make this work as well 386 00:23:19.345 --> 00:23:23.962 But the reason why I told you this 387 00:23:23.962 --> 00:23:27.712 is to tell you that you can use RPC 388 00:23:27.712 --> 00:23:29.206 and also property replication 389 00:23:29.206 --> 00:23:32.846 as well to make this work 390 00:23:32.846 --> 00:23:36.846 Here, I'll change it back to how it was 391 00:23:36.846 --> 00:23:40.042 so that both RPC and 392 00:23:40.042 --> 00:23:43.292 property replication is used 393 00:23:43.292 --> 00:23:45.962 Here, except for this part 394 00:23:45.962 --> 00:23:49.002 I'll do ctrl z 395 00:23:52.161 --> 00:23:54.861 Great 396 00:23:54.861 --> 00:23:58.581 On get lifetime as well 397 00:23:59.801 --> 00:24:02.551 we'll take it back to the original code 398 00:24:02.551 --> 00:24:06.842 and on bulletCount, we'll put UPROPERTY, replicated back to its shape 399 00:24:06.842 --> 00:24:11.099 This means I'll just keep the property replication and use that 400 00:24:11.099 --> 00:24:16.939 We learned two ways to make fire work 401 00:24:16.939 --> 00:24:21.242 Up until now was fire 402 00:24:21.242 --> 00:24:24.392 I showed you that 403 00:24:24.392 --> 00:24:28.343 on fire, you can use property replication and RPC 404 00:24:28.343 --> 00:24:30.643 and that you don't have to 405 00:24:30.643 --> 00:24:33.823 use RPC only or property replication only 406 00:24:33.823 --> 00:24:37.161 but that both work 407 00:24:37.161 --> 00:24:40.663 through that example 408 00:24:40.663 --> 00:24:42.623 This was fire 409 00:24:42.911 --> 00:24:45.351 Reload using RPC 410 00:24:47.070 --> 00:24:49.101 Next is reload 411 00:24:49.101 --> 00:24:51.551 It will use RPC 412 00:24:51.551 --> 00:24:54.342 RPC, again, the clients 413 00:24:56.202 --> 00:24:58.901 receives a certain input from the server 414 00:25:01.281 --> 00:25:03.401 and requests to the server 415 00:25:07.401 --> 00:25:09.522 Then the server 416 00:25:11.401 --> 00:25:16.281 performs a logic according to that request 417 00:25:17.241 --> 00:25:22.491 Here, when requesting to the server, what type of RPC is it? 418 00:25:22.491 --> 00:25:23.342 Server RPC 419 00:25:24.861 --> 00:25:28.261 It uses server RPC to request to the server 420 00:25:28.261 --> 00:25:33.802 Then the server performs the logic 421 00:25:33.802 --> 00:25:36.761 and the result is sent back to the client 422 00:25:38.602 --> 00:25:45.841 Once that sent the visualization on reload is performed 423 00:25:45.841 --> 00:25:51.482 How will that request work here 424 00:25:51.482 --> 00:25:54.432 It was Multicast until now 425 00:25:54.432 --> 00:25:57.778 but for reload 426 00:25:57.778 --> 00:26:01.358 we'll use client RPC 427 00:26:04.721 --> 00:26:07.221 We'll try using client RPC to do that 428 00:26:07.221 --> 00:26:07.721 Why? 429 00:26:07.721 --> 00:26:09.861 For reload 430 00:26:09.861 --> 00:26:12.761 we'll say that only that client 431 00:26:12.761 --> 00:26:15.002 needs to receive the result 432 00:26:15.002 --> 00:26:19.491 Of course we can make every client see the reload animation 433 00:26:19.491 --> 00:26:22.041 but reload itself might not 434 00:26:22.041 --> 00:26:24.751 matter greatly to other users, the animation itself 435 00:26:24.751 --> 00:26:28.522 But for the user reloading, the animation is very important 436 00:26:28.522 --> 00:26:32.972 Why? Because the code that updates the UI once reload is done 437 00:26:32.972 --> 00:26:36.042 is in the client 438 00:26:36.042 --> 00:26:37.692 So here 439 00:26:37.692 --> 00:26:42.762 client requests communication using server RPC to the server 440 00:26:42.762 --> 00:26:46.112 then the server performs core logic 441 00:26:46.112 --> 00:26:50.802 and sends client RPC to the client 442 00:26:50.802 --> 00:26:54.763 Then client, again receives the visualization message 443 00:26:54.763 --> 00:26:57.813 and does the rendering itself 444 00:26:57.813 --> 00:27:00.424 That's how it'll work 445 00:27:00.441 --> 00:27:02.841 Come to Visual Studio 446 00:27:02.841 --> 00:27:05.801 and to NetTPSCharacter header file 447 00:27:07.421 --> 00:27:10.221 On the very bottom, public 448 00:27:13.281 --> 00:27:19.281 We're going to add a Multiplayer on reload 449 00:27:19.281 --> 00:27:26.602 UFUNCTION, and we're going to use server RPC so put server and reliable 450 00:27:26.602 --> 00:27:28.802 When there's an input in the server 451 00:27:28.802 --> 00:27:33.161 this request must happen 452 00:27:33.161 --> 00:27:36.761 It can't be omitted since it's an important input from a client 453 00:27:36.761 --> 00:27:38.604 So we put reliable 454 00:27:38.604 --> 00:27:42.054 but visualization 455 00:27:42.054 --> 00:27:44.744 doesn't matter as greatly 456 00:27:44.744 --> 00:27:46.544 The visualization 457 00:27:46.544 --> 00:27:49.961 can be seen or not to the user 458 00:27:49.961 --> 00:27:52.511 Those can work with unreliable as well 459 00:27:52.511 --> 00:27:56.841 But reload animation for the client is very important 460 00:27:56.841 --> 00:27:57.641 Why? 461 00:27:57.641 --> 00:28:01.841 Because there is a code that updates the UI 462 00:28:01.841 --> 00:28:04.362 once the reload animation is over 463 00:28:04.362 --> 00:28:06.062 So those parts 464 00:28:06.062 --> 00:28:07.912 need to have reliable 465 00:28:07.912 --> 00:28:12.042 when sending a client RPC and the data 466 00:28:12.042 --> 00:28:15.192 I'll mention that again later on 467 00:28:15.192 --> 00:28:22.404 So we'll put void serverRPC 468 00:28:22.404 --> 00:28:27.454 ServerRPC_Reload 469 00:28:27.454 --> 00:28:31.624 We have ServerRPC_Reload on reload 470 00:28:31.624 --> 00:28:32.824 and in addition to that 471 00:28:32.824 --> 00:28:36.084 let's make the client RPC as well 472 00:28:36.084 --> 00:28:39.134 This time, not server 473 00:28:39.134 --> 00:28:41.322 and instead client 474 00:28:41.344 --> 00:28:45.804 This one too, I'll put reliable 475 00:28:45.804 --> 00:28:52.681 The reason is, as I keep telling you, the animation needs to be performed to update the UI 476 00:28:52.681 --> 00:28:56.231 so it's done as reliable 477 00:28:56.231 --> 00:29:02.361 I'll say void ClientRPC_Reload 478 00:29:02.361 --> 00:29:05.442 Let's add implementation for the two functions 479 00:29:09.102 --> 00:29:13.661 Added one on NetTPSCharacter cpp and the other one as well 480 00:29:15.130 --> 00:29:16.950 I'll add implementation 481 00:29:18.810 --> 00:29:21.842 I'll move these two, server RPC and client RPC 482 00:29:21.842 --> 00:29:27.321 to under ReloadPistol, like this 483 00:29:28.764 --> 00:29:32.064 Let's keep going 484 00:29:32.064 --> 00:29:36.914 First, from the client side, ReleasePistol 485 00:29:36.914 --> 00:29:40.322 Oh sorry ReloadPistol, then what happens? 486 00:29:40.322 --> 00:29:44.222 This part needs to be checked by the client 487 00:29:44.222 --> 00:29:48.361 Animation, this part is sent with Multicast 488 00:29:48.984 --> 00:29:53.944 and isReloading will work 489 00:29:53.944 --> 00:29:58.441 These are done on the client side 490 00:29:58.441 --> 00:30:02.502 But let's move this part to where? 491 00:30:03.764 --> 00:30:05.864 To the client RPC 492 00:30:05.864 --> 00:30:08.314 We have to take these to the client 493 00:30:08.314 --> 00:30:09.937 but there's a problem here 494 00:30:09.937 --> 00:30:13.987 If a user inputs reload 495 00:30:13.987 --> 00:30:15.857 the animation will first be shown 496 00:30:15.857 --> 00:30:18.807 It doesn't really have to ask the server about it 497 00:30:18.807 --> 00:30:19.964 here 498 00:30:19.964 --> 00:30:21.564 The animation is shown 499 00:30:21.564 --> 00:30:26.164 and once that's done, init Ammo ui 500 00:30:26.164 --> 00:30:28.814 function is called 501 00:30:28.814 --> 00:30:30.842 On NetPlayerAnim instance 502 00:30:32.984 --> 00:30:38.362 when this AnimNotify OnReloadFinish event function is called 503 00:30:38.362 --> 00:30:42.481 InitAmmoUI function on player is called 504 00:30:42.481 --> 00:30:45.731 That way the UI is updated 505 00:30:45.731 --> 00:30:48.644 Then the animation needs to be called properly 506 00:30:48.644 --> 00:30:53.184 and this InitAmmoUI on player also has to be called 507 00:30:53.184 --> 00:30:57.334 This InitAmmoUI happens on the client side 508 00:30:57.334 --> 00:30:59.082 What's important here? 509 00:30:59.082 --> 00:31:03.544 This part. Here it's changing the data 510 00:31:03.544 --> 00:31:05.944 This part that changes the data 511 00:31:05.944 --> 00:31:09.344 isn't what the client should do but what the server should do 512 00:31:09.344 --> 00:31:12.344 Visualization is done where? 513 00:31:12.344 --> 00:31:13.444 By the client 514 00:31:13.444 --> 00:31:17.522 but this data changing part is on the server 515 00:31:17.522 --> 00:31:20.022 So we'll have to separate them 516 00:31:20.022 --> 00:31:22.584 So once animation is done 517 00:31:22.584 --> 00:31:27.544 InitAmmoUI will request a server RPC 518 00:31:27.570 --> 00:31:30.511 From where? I'll explain it once again 519 00:31:30.511 --> 00:31:35.191 ReloadPistol input comes in and animation plays 520 00:31:35.191 --> 00:31:39.091 and when that happens, event function is called 521 00:31:39.091 --> 00:31:40.482 Notify even is called 522 00:31:40.482 --> 00:31:42.482 when the animation is about to be over 523 00:31:42.482 --> 00:31:45.801 Then InitAmmoUI is called 524 00:31:45.801 --> 00:31:47.801 Data is updated at that moment 525 00:31:47.801 --> 00:31:50.204 and this isn't on the client 526 00:31:50.204 --> 00:31:54.404 but telling the server 'update the data 527 00:31:54.404 --> 00:31:56.244 since my animation is over' 528 00:31:56.244 --> 00:31:58.844 So InitAmmoUI's this part 529 00:31:58.844 --> 00:32:01.804 is what we have to work with server RPC 530 00:32:01.804 --> 00:32:06.944 Here, call ServerRPC Reload 531 00:32:06.944 --> 00:32:09.144 then where do all these go? 532 00:32:09.144 --> 00:32:12.294 These will go to server RPC 533 00:32:12.294 --> 00:32:16.921 and the part that updates the UI must go where? 534 00:32:16.924 --> 00:32:18.874 To client RPC 535 00:32:18.874 --> 00:32:22.284 From server RPC, this bulletCount only goes there 536 00:32:22.284 --> 00:32:26.702 and everything else will all have to go to client RPC 537 00:32:27.682 --> 00:32:31.882 Again, a user clicks on reload 538 00:32:31.882 --> 00:32:34.604 and server RPC is requested when the animation is done 539 00:32:34.604 --> 00:32:39.484 then server RPC updates data 540 00:32:39.484 --> 00:32:41.804 and to the client 541 00:32:41.804 --> 00:32:45.954 it says 'hey your animation is done 542 00:32:45.954 --> 00:32:49.001 so update the UI 543 00:32:49.001 --> 00:32:50.401 and effects' 544 00:32:50.401 --> 00:32:56.121 Here the client RPC is called 545 00:32:56.121 --> 00:33:03.622 Then, using RPC communication, client first receives input 546 00:33:06.402 --> 00:33:09.961 then with that input, animation is performed 547 00:33:12.404 --> 00:33:14.544 Then what do we do? 548 00:33:14.544 --> 00:33:17.944 When this animation ends, InitAmmoUI is updated 549 00:33:17.944 --> 00:33:20.642 and here it requests to the server 550 00:33:21.462 --> 00:33:22.601 Right here 551 00:33:24.464 --> 00:33:25.664 to the server 552 00:33:25.664 --> 00:33:30.704 Then the server receives this as a server RPC 553 00:33:30.704 --> 00:33:32.504 and what does it do? 554 00:33:32.504 --> 00:33:37.461 It updates bulletCount, makes data for bulletCount 555 00:33:37.464 --> 00:33:40.124 and then again to the client 556 00:33:40.124 --> 00:33:46.862 it sends to the client saying 'the bulletCount is updated 557 00:33:47.802 --> 00:33:51.202 so update the UI with this data' 558 00:33:51.202 --> 00:33:54.361 Then this will be performed to update the screen 559 00:33:55.001 --> 00:33:59.101 Then from the client RPC it sent it to the client 560 00:33:59.101 --> 00:34:03.561 then here the mainUI parts 561 00:34:03.561 --> 00:34:07.611 must be performed only when there is a mainUI 562 00:34:07.611 --> 00:34:09.222 That's what we did so far 563 00:34:09.222 --> 00:34:11.821 So here as well, if 564 00:34:15.021 --> 00:34:20.022 mainUI, when there is a main UI 565 00:34:21.304 --> 00:34:26.484 The parts about mainUI will be perfromed when there is a mainUI 566 00:34:26.484 --> 00:34:30.834 Reload will be done when the client RPC is called from the server 567 00:34:30.834 --> 00:34:35.234 and everything is updated 568 00:34:35.234 --> 00:34:37.721 Let's build 569 00:34:43.925 --> 00:34:45.625 Good 570 00:34:45.625 --> 00:34:50.625 Then let's go to Unreal editor and open a server window 571 00:34:50.625 --> 00:34:53.341 and a client window 572 00:34:54.565 --> 00:34:58.185 First I'll take a pistol from the server 573 00:34:58.185 --> 00:35:00.935 and shoot, the UI is updating 574 00:35:00.935 --> 00:35:02.435 Let me press R 575 00:35:02.435 --> 00:35:05.282 Then it updates 576 00:35:05.282 --> 00:35:07.182 I can fire again 577 00:35:07.182 --> 00:35:12.082 Again, the UI is updated, and I can fire more 578 00:35:12.085 --> 00:35:15.865 On the client as well 579 00:35:15.865 --> 00:35:18.365 I'll use all the bullets 580 00:35:18.365 --> 00:35:19.765 I can't fire anymore 581 00:35:19.765 --> 00:35:22.121 Update by pressing R 582 00:35:22.945 --> 00:35:27.765 Is the screen updated? It isn't 583 00:35:27.765 --> 00:35:32.762 It isn't being updated on the client window 584 00:35:32.762 --> 00:35:34.362 Pew pew pew pew 585 00:35:34.362 --> 00:35:38.085 It worked on the server but on the client, it isn't working 586 00:35:38.085 --> 00:35:39.535 Why does this happen? 587 00:35:39.535 --> 00:35:42.645 We'll learn that while making a log 588 00:35:43.381 --> 00:35:46.945 First, bulletCount is updated on server RPC 589 00:35:46.945 --> 00:35:51.105 Then how does the client use this bulletCount 590 00:35:51.105 --> 00:35:56.121 It adds bullets using this updated bulletCount 591 00:35:56.121 --> 00:35:59.851 Then let's see if this data is being updated properly 592 00:35:59.851 --> 00:36:03.711 First here, UE_LOG 593 00:36:03.725 --> 00:36:09.402 LogTemp Warning, TEXT 594 00:36:10.862 --> 00:36:15.241 bulletCount of server RPC 595 00:36:15.241 --> 00:36:19.291 We're going to take this bulletCount here 596 00:36:19.291 --> 00:36:24.001 bulletCount on %d 597 00:36:24.001 --> 00:36:27.501 Then on client RPC 598 00:36:27.501 --> 00:36:30.625 Before calling the client RPC, this was done 599 00:36:30.625 --> 00:36:34.042 and coming back here let's see 600 00:36:34.042 --> 00:36:35.992 Before working on the bullet UI settings 601 00:36:35.992 --> 00:36:39.721 we'll input the bulletCount first 602 00:36:42.425 --> 00:36:44.445 Great, how does it work? 603 00:36:44.445 --> 00:36:48.605 It was sent to the server and the server updated bulletCount data 604 00:36:48.605 --> 00:36:52.255 and using client RPC, with that updated data 605 00:36:52.255 --> 00:36:54.902 the screen is updated 606 00:36:54.902 --> 00:36:57.585 But the reason this doesn't work properly 607 00:36:57.585 --> 00:36:59.285 The reason the screen isn't updating 608 00:36:59.285 --> 00:37:01.925 There must be a problem 609 00:37:01.925 --> 00:37:03.875 I put this bulletCount 610 00:37:03.875 --> 00:37:06.081 to find what the problem is 611 00:37:06.801 --> 00:37:08.401 Let's see 612 00:37:08.401 --> 00:37:10.682 First, on window 613 00:37:14.142 --> 00:37:17.542 there is Output Log window under message log 614 00:37:17.542 --> 00:37:21.582 Let's see there 615 00:37:21.582 --> 00:37:22.782 Good 616 00:37:22.782 --> 00:37:27.482 Then on filter, I'll see Warning only 617 00:37:27.482 --> 00:37:29.762 Like this 618 00:37:29.762 --> 00:37:36.345 Then I'll play, client as well 619 00:37:36.345 --> 00:37:40.845 Take and fire pistol 620 00:37:40.845 --> 00:37:43.295 The bulletCount is obviously 0 621 00:37:43.295 --> 00:37:46.201 Let me press on reload here 622 00:37:46.201 --> 00:37:47.551 It reloads 623 00:37:47.551 --> 00:37:52.151 There's something on the screen 624 00:37:52.151 --> 00:37:54.241 Let's see 625 00:37:57.802 --> 00:38:03.682 On the output log, on the server, what happened? 626 00:38:03.682 --> 00:38:08.361 It says ServerRPC bulletCount is 10 627 00:38:08.361 --> 00:38:12.751 Right here 628 00:38:12.751 --> 00:38:15.501 ServerRPC bulletCount is 10 629 00:38:15.501 --> 00:38:19.471 and client RPC is 0 630 00:38:19.471 --> 00:38:20.521 Isn't that odd? 631 00:38:20.521 --> 00:38:23.522 On the server, the data was updated to bulletCount 10 632 00:38:23.522 --> 00:38:26.222 but the client that received it 633 00:38:26.222 --> 00:38:32.042 still has it at 0, the data wasn't updated 634 00:38:32.042 --> 00:38:34.542 The reason is 635 00:38:34.542 --> 00:38:38.442 Did we have bulletCount be replicated? No 636 00:38:38.442 --> 00:38:41.092 Go to header 637 00:38:41.092 --> 00:38:46.282 where this bulletCount is declared, it is replicated 638 00:38:46.282 --> 00:38:49.881 And on the very bottom 639 00:38:51.562 --> 00:38:56.362 we also added implementation for that 640 00:38:56.362 --> 00:38:57.802 It must be done automatically 641 00:38:57.802 --> 00:38:59.602 but why isn't it being updated? 642 00:38:59.602 --> 00:39:02.361 Let's see another thing on tick 643 00:39:04.682 --> 00:39:06.402 From tick function 644 00:39:08.442 --> 00:39:10.481 let's add something for this 645 00:39:12.405 --> 00:39:16.785 UE_LOG, LogTemp 646 00:39:18.601 --> 00:39:22.081 It's kind of inconvenient when we try to work with the console 647 00:39:22.081 --> 00:39:25.731 For this part, later on, we'll use 648 00:39:25.731 --> 00:39:27.841 macro to make it better to work with 649 00:39:27.841 --> 00:39:35.762 Warning, text, tick bulletCount 650 00:39:35.762 --> 00:39:39.705 We'll see how this bulletCount is called 651 00:39:41.435 --> 00:39:44.635 And this one only needs to be left on client 652 00:39:44.635 --> 00:39:45.585 so I'll add one thing 653 00:39:48.481 --> 00:39:51.231 NetMode 654 00:39:51.231 --> 00:39:54.601 When NetMode is at client 655 00:39:54.601 --> 00:39:57.162 GetNetMode 656 00:39:58.925 --> 00:40:02.425 sends over these NetModes 657 00:40:02.425 --> 00:40:06.085 With this, we can know where this is 658 00:40:06.085 --> 00:40:10.321 whether it is running on the client window or the server window 659 00:40:10.321 --> 00:40:16.442 Here, I'll put NM_Client on NetMode 660 00:40:16.481 --> 00:40:18.981 Running on client 661 00:40:18.981 --> 00:40:22.081 and this will be output on the screen 662 00:40:22.081 --> 00:40:25.381 only when there is mainUI 663 00:40:25.381 --> 00:40:27.781 So that it works selectively 664 00:40:29.922 --> 00:40:31.561 Good 665 00:40:36.961 --> 00:40:41.322 Come back and click on clear 666 00:40:43.045 --> 00:40:44.145 Play 667 00:40:44.145 --> 00:40:46.395 On the server, there's nothing on the output log 668 00:40:46.395 --> 00:40:48.245 When I play the client 669 00:40:48.245 --> 00:40:52.042 The bulletCount is 10 670 00:40:52.042 --> 00:40:53.392 Right? 671 00:40:53.392 --> 00:40:57.645 Now I'll take and fire the pistol on the client window 672 00:40:57.645 --> 00:41:00.705 Then the bulletCount is at 0 673 00:41:00.705 --> 00:41:01.955 Pressing R 674 00:41:01.955 --> 00:41:05.485 it showed 0 just now 675 00:41:05.485 --> 00:41:08.245 Now the animation is done and look 676 00:41:09.341 --> 00:41:11.791 The count has changed to 10 677 00:41:11.791 --> 00:41:15.541 The reason why the bulletCount is at 10 678 00:41:15.541 --> 00:41:16.922 is here 679 00:41:16.922 --> 00:41:21.241 Zooming in here 680 00:41:21.241 --> 00:41:25.325 The server RPC changed the bulletCount to 10 681 00:41:25.325 --> 00:41:29.525 Then the client RPC log says 0 682 00:41:29.525 --> 00:41:32.975 Tick also says 0 683 00:41:32.975 --> 00:41:35.381 but then after that it's 10 684 00:41:36.241 --> 00:41:39.191 Here, we can know 685 00:41:39.191 --> 00:41:43.282 that RPC called the moment we call it 686 00:41:43.282 --> 00:41:47.417 but what about property replication? 687 00:41:47.417 --> 00:41:51.097 It isn't being synced right away 688 00:41:51.097 --> 00:41:54.747 It has its own update cycle 689 00:41:54.747 --> 00:41:58.601 On that cycle, the data is matched 690 00:41:58.601 --> 00:42:00.401 There was this variable that we worked with 691 00:42:00.401 --> 00:42:05.001 which is Net Update Frequency 692 00:42:05.001 --> 00:42:08.025 on actor, do you remember? 693 00:42:08.025 --> 00:42:11.625 We had BP NetActor 694 00:42:11.625 --> 00:42:14.125 Selecting this, 695 00:42:14.125 --> 00:42:17.842 there's this variable Net Update Frequency 696 00:42:17.845 --> 00:42:20.465 Here's Net Update Frequency 697 00:42:20.465 --> 00:42:24.565 and what does this mean? 698 00:42:24.565 --> 00:42:25.842 It says 199 699 00:42:27.226 --> 00:42:30.706 which is the cycle of the server and client being updated 700 00:42:30.706 --> 00:42:34.201 It's set at 100 so it will be called 100 times a second 701 00:42:34.201 --> 00:42:39.486 But it would be maintained or not depending on network circumstances 702 00:42:39.486 --> 00:42:42.666 So this Net Update Frequency 703 00:42:42.682 --> 00:42:43.732 The cycle 704 00:42:43.732 --> 00:42:46.132 Depending on the cycle 705 00:42:46.132 --> 00:42:51.201 the bulletCount property replication happens 706 00:42:51.201 --> 00:42:53.551 As you saw on the screen 707 00:42:53.551 --> 00:42:58.162 Here, RPC says this 708 00:42:58.162 --> 00:43:01.462 Right after calling, client communication happens 709 00:43:01.462 --> 00:43:03.386 and property replication 710 00:43:03.386 --> 00:43:05.086 just follows its cycle 711 00:43:05.086 --> 00:43:09.846 so the timing the two are updated don't match 712 00:43:09.846 --> 00:43:12.096 So even though the server said 10 713 00:43:12.096 --> 00:43:14.321 it's 0 on the client 714 00:43:14.321 --> 00:43:16.571 so here the client RPC updates 715 00:43:16.571 --> 00:43:17.971 to update the UI 716 00:43:17.971 --> 00:43:19.986 but what's the bulletCount? 0 717 00:43:19.986 --> 00:43:22.536 So it doesn't have anything to update 718 00:43:22.536 --> 00:43:27.386 So, the moment we're trying to update on NetTPSCharacter 719 00:43:27.386 --> 00:43:28.336 Right here 720 00:43:28.336 --> 00:43:31.162 What's the bulletCount here? 721 00:43:31.162 --> 00:43:32.612 0 722 00:43:32.612 --> 00:43:36.941 As soon as this changed this part had to be performed but it didn't 723 00:43:38.106 --> 00:43:39.856 That's why this problem occurred 724 00:43:39.856 --> 00:43:42.786 Then what should we do? It's very simple 725 00:43:42.786 --> 00:43:47.782 We need to sync property replication and RPC 726 00:43:47.782 --> 00:43:51.762 There will be several ways but we'll use the parameter 727 00:43:51.763 --> 00:43:54.422 and update bulletCount here 728 00:43:54.442 --> 00:43:56.392 Syncing with that value 729 00:43:56.392 --> 00:43:59.442 We learned this also on fire 730 00:43:59.442 --> 00:44:01.142 Next 731 00:44:01.142 --> 00:44:06.942 The bulletCount is being updated on 100%, MaxBulletCount 732 00:44:06.942 --> 00:44:09.092 So we can change this bulletCount 733 00:44:09.092 --> 00:44:13.562 to MaxBulletCount which changes the data 734 00:44:13.563 --> 00:44:16.763 and then it will 735 00:44:16.763 --> 00:44:18.162 reload 736 00:44:18.182 --> 00:44:21.432 Why? Tick follows right up 737 00:44:21.432 --> 00:44:24.321 to put MaxBulletCount on bulletCount 738 00:44:24.321 --> 00:44:27.321 Handing over the bulletCount means 739 00:44:27.321 --> 00:44:29.826 sending it over to parameter 740 00:44:29.826 --> 00:44:33.226 and then 741 00:44:33.226 --> 00:44:37.776 put update bulletCount 742 00:44:37.776 --> 00:44:42.562 which will be used to update bulletCount 743 00:44:42.563 --> 00:44:45.282 This part will also have to go in the implementation, of course 744 00:44:45.302 --> 00:44:49.702 Then as a ClientRPC Reload factor 745 00:44:49.702 --> 00:44:53.162 when this is called on the server RPC, bulletCount data is cleared 746 00:44:53.162 --> 00:44:58.006 and to this RPC function, update bulletCount, bulletCount data comes in 747 00:44:58.006 --> 00:45:01.106 then the value is updated to this value 748 00:45:01.106 --> 00:45:04.056 Then the data will be synced 749 00:45:04.056 --> 00:45:06.861 Another is 750 00:45:06.881 --> 00:45:10.946 bulletCount will be updated to MaxBulletCount anyways 751 00:45:10.946 --> 00:45:12.796 so when client RPC is called 752 00:45:12.796 --> 00:45:17.946 it can just fill it up to MaxBulletCount instead of just any other bulletCount 753 00:45:17.946 --> 00:45:19.846 This is the same 754 00:45:19.846 --> 00:45:24.282 Then with this, let's see if it works 755 00:45:24.282 --> 00:45:29.382 I'll first erase this part with UE_LOG 756 00:45:29.382 --> 00:45:31.841 because it might show on the screen 757 00:45:31.841 --> 00:45:33.791 On tick as well 758 00:45:33.791 --> 00:45:38.962 I'll erase this part where it called 759 00:45:42.522 --> 00:45:43.522 Build 760 00:45:46.321 --> 00:45:50.902 The part that we worked on 761 00:45:53.042 --> 00:45:57.802 The Reload part will work 762 00:46:00.162 --> 00:46:03.182 We made it work properly on the client side 763 00:46:05.042 --> 00:46:07.522 Right 764 00:46:10.562 --> 00:46:15.001 What did it do on client RPC reload 765 00:46:15.001 --> 00:46:18.762 It kept taking it to MaxBullet 766 00:46:20.162 --> 00:46:24.142 It's done building so let's check 767 00:46:25.442 --> 00:46:27.492 Play 768 00:46:27.492 --> 00:46:31.081 This data on output log isn't being printed anymore 769 00:46:31.081 --> 00:46:33.181 We don't need this 770 00:46:35.481 --> 00:46:40.631 On the server, taking and firing the pistol 771 00:46:40.631 --> 00:46:42.231 the UI is updating 772 00:46:42.231 --> 00:46:44.682 and pressing on Reload 773 00:46:44.682 --> 00:46:46.632 it also updates 774 00:46:46.632 --> 00:46:49.782 Now on the client, take the pistol over there 775 00:46:49.782 --> 00:46:51.282 and I'll fire 776 00:46:51.282 --> 00:46:54.126 The bulletCount must be 0, and it is 777 00:46:54.126 --> 00:46:56.476 Press on Reload, the animation shows 778 00:46:56.476 --> 00:46:59.706 and the bulletCount is updated 779 00:46:59.706 --> 00:47:02.726 What's the reason it shows up properly on the screen? 780 00:47:02.726 --> 00:47:06.426 The timing of bulletCount and RPC being updated are different 781 00:47:06.426 --> 00:47:08.066 They aren't the same 782 00:47:08.066 --> 00:47:13.522 But on RPC, data is updated to MaxBulletCount anyways 783 00:47:13.522 --> 00:47:18.001 so the UI was added by MaxBulletCount 784 00:47:18.002 --> 00:47:20.461 It can also be done by using parameter 785 00:47:20.481 --> 00:47:25.562 or if that's a waste of packet 786 00:47:25.563 --> 00:47:27.513 without having to do that 787 00:47:27.513 --> 00:47:30.913 since here, it just has to fill the UI with this data 788 00:47:30.913 --> 00:47:35.181 it was set to just make it MaxBulletCount 789 00:47:35.181 --> 00:47:39.321 This was reload 790 00:47:39.321 --> 00:47:42.121 Let's summarize what we've learned in this unit 791 00:47:42.846 --> 00:47:43.566 Fire using RPC Declare ServerRPCFire() function 792 00:47:43.567 --> 00:47:44.206 Go to NetTPSCharacter.h Add an RPC function ServerRPCFire() which will be performed in the server to fire 793 00:47:44.207 --> 00:47:44.826 Implementation of ServerRPCFire() function Go to NetTPSCharacter.cpp 794 00:47:44.827 --> 00:47:45.426 Add ServerRPCFire() implementation Move everything on fire of Fire() function to ServerRPCFire() 795 00:47:45.427 --> 00:47:46.027 Declare MulticastRPCFire() 796 00:47:46.027 --> 00:47:46.846 Fire logic is performed in the server but effect and UI are performed in the client Go to NetTPSCharacter.h 797 00:47:46.847 --> 00:47:47.588 Add MulticastRPCFire() declaration on NetMulticast RPC option With parameter, receive collision result 798 00:47:47.588 --> 00:47:48.228 MulticastRPCFire() function implementation Go to NetTPSCharacter.cpp 799 00:47:48.229 --> 00:47:48.966 Add MulticastRPCFire() implementation Take effect, mainUI call, animation from ServerRPCFire() 800 00:47:48.967 --> 00:47:49.746 ServerRPCFire() function revision When bHit is true, SpawnEmitterAtLocation() function call is moved to MulticastRPCFire() 801 00:47:49.747 --> 00:47:50.386 Code removing bullets and controlling mainUI and animation is move to MulticastRPCFire() 802 00:47:50.387 --> 00:47:51.046 Call MulticastRPCFire() function at the last part BulletCount replication 803 00:47:51.047 --> 00:47:51.826 Go to NetTPSCharacter.h to sync the remaining bullets Set Replicated option for bulletCount variable 804 00:47:51.826 --> 00:47:52.586 Go to NetTPSCharacter.cpp Add bulletCount replication to GetLifetimeReplicatedProps() function 805 00:47:52.586 --> 00:47:53.267 Reload using RPC Add Server, Client RPCReload 806 00:47:53.267 --> 00:47:53.947 Declare ServerRPCReload() to NetTPSCharacter.h Add ClientRPCReload() function which uses client RPC option 807 00:47:53.947 --> 00:47:54.667 Go to NetTPSCharacter.cpp 808 00:47:54.667 --> 00:47:55.387 When reload animation is done AnimNotify_OnReloadFinish() event happens in NetPlayerAnimInstance.cpp 809 00:47:55.387 --> 00:47:56.047 It calls InitAmmoUI() of NetTPSCharacter.cpp InitAmmoUI() calls ServerRPCReload() 810 00:47:56.047 --> 00:47:56.726 ServerRPCReload() resets bulletCount and calls ClientRPCReload() 811 00:47:56.726 --> 00:47:57.446 ClientRPCReload() works on mainUI and finishes reload 812 00:47:57.446 --> 00:47:58.446 The End