WEBVTT 1 00:00:04.721 --> 00:00:09.022 Realistic Immersive Content: Advanced Unreal Engine AR Template and Basic Components 2 00:00:23.760 --> 00:00:26.660 When one uses their own smartphone's front camera 3 00:00:26.660 --> 00:00:28.400 To film their own face 4 00:00:28.400 --> 00:00:33.040 Let's learn about recognizing the face part alone 5 00:00:33.040 --> 00:00:34.959 Out of the entire image 6 00:00:34.959 --> 00:00:38.880 And we will implement a function that 7 00:00:38.880 --> 00:00:41.200 Adds an image, such as a party mask, right on the face area 8 00:00:41.200 --> 00:00:43.080 After the face recognition takes place 9 00:00:43.080 --> 00:00:46.240 Moving beyond only recognizing the face as a whole 10 00:00:46.240 --> 00:00:49.919 We will use functions from Google ARCore API 11 00:00:49.919 --> 00:00:52.160 And track data for specific parts of face 12 00:00:52.160 --> 00:00:55.439 Such as the tip of the nose or the forehead 13 00:00:55.439 --> 00:00:58.200 We will be practicing this together 14 00:00:59.320 --> 00:01:03.560 Today, we will use the front camera of a smartphone 15 00:01:03.560 --> 00:01:05.000 And make it recognize the face 16 00:01:05.000 --> 00:01:09.440 And add special objects to parts of the face 17 00:01:09.440 --> 00:01:13.000 So that we can add various effects 18 00:01:13.000 --> 00:01:15.920 To the face that the camera is filming 19 00:01:16.396 --> 00:01:19.857 Face Recognition 20 00:01:20.680 --> 00:01:24.720 Before doing that, let's first organize 21 00:01:24.720 --> 00:01:28.720 All the nodes we worked with in the last class 22 00:01:28.720 --> 00:01:30.879 Go to Content Drawer 23 00:01:30.879 --> 00:01:35.639 HunetPlayerPawn, open its Blueprint Settings 24 00:01:35.639 --> 00:01:40.040 We worked with quite a lot of nodes last time 25 00:01:40.040 --> 00:01:45.959 So let's make them into functions to process them 26 00:01:45.959 --> 00:01:51.480 First, this task for the screensaver at Begin Play 27 00:01:51.480 --> 00:01:57.199 And these that import screen resolution 28 00:01:57.199 --> 00:02:01.440 Let's put them into a function for such pre-works 29 00:02:01.440 --> 00:02:06.959 Go to FUNCTIONS, and click on the plus button 30 00:02:08.479 --> 00:02:10.199 And let's create a new function 31 00:02:10.199 --> 00:02:14.059 Let's name it ReadyForAR 32 00:02:16.759 --> 00:02:20.719 We created a function called ReadyForAR 33 00:02:22.679 --> 00:02:27.320 And from this Screensaver from Event Graph 34 00:02:27.320 --> 00:02:30.870 To our Game User Settings 35 00:02:30.870 --> 00:02:36.119 Ctrl+X to cut this part 36 00:02:36.119 --> 00:02:40.399 And let's paste it into the function, ReadyForAR 37 00:02:40.399 --> 00:02:46.919 For which we use Ctrl+V 38 00:02:46.919 --> 00:02:49.279 And connect the Execution Pin 39 00:02:49.279 --> 00:02:53.679 This will complete our function 40 00:02:53.679 --> 00:02:59.240 And let's connect this Execution Pin as well 41 00:03:01.080 --> 00:03:07.000 And for this completed ReadyForAR node 42 00:03:07.000 --> 00:03:12.160 Let's stick it before our 'Start AR Session' 43 00:03:12.160 --> 00:03:15.759 From where it recognizes the ground at Tick 44 00:03:15.759 --> 00:03:20.320 To where it spawns actor on that recognized ground 45 00:03:20.320 --> 00:03:26.119 Let's create another function for this part 46 00:03:26.119 --> 00:03:33.039 And name it SpawnActorToGround 47 00:03:33.039 --> 00:03:36.880 Let's make that function 48 00:03:36.880 --> 00:03:39.440 And now, again at Event Graph 49 00:03:39.440 --> 00:03:44.960 Let's group all these nodes connected to the Event Tick 50 00:03:44.960 --> 00:03:47.959 Select them all 51 00:03:50.279 --> 00:03:52.880 So this is excluding Event Tick node 52 00:03:52.880 --> 00:03:57.759 And it includes all other nodes connected to the Event Tick node 53 00:03:57.759 --> 00:04:03.199 Ctrl+X again to cut 54 00:04:03.199 --> 00:04:06.639 Make sure to go back and see if you missed anything 55 00:04:06.639 --> 00:04:09.600 Here, go to SpawnActorToGround function 56 00:04:09.600 --> 00:04:13.000 By double clicking, and for this body part 57 00:04:13.000 --> 00:04:17.679 Let's Ctrl+V to paste what we have 58 00:04:17.679 --> 00:04:21.880 And then finally connect the Execution Pin 59 00:04:21.880 --> 00:04:25.640 This will complete the function 60 00:04:25.640 --> 00:04:28.399 Now, back to Event Graph 61 00:04:28.399 --> 00:04:32.239 Now, let's connect SpawnActorToGround 62 00:04:32.239 --> 00:04:36.040 That we just made 63 00:04:36.040 --> 00:04:39.799 And then compile and save 64 00:04:39.799 --> 00:04:43.440 For now, Ground Detection pat is over 65 00:04:43.440 --> 00:04:46.919 So we can disconnect this part 66 00:04:48.399 --> 00:04:51.440 And then for 'Start AR Session' 67 00:04:51.440 --> 00:04:55.279 Last time when we worked on this 'Start AR Session' part 68 00:04:55.279 --> 00:04:57.760 We used a Session Config file 69 00:04:57.760 --> 00:05:01.119 Which was for recognizing the ground area 70 00:05:01.119 --> 00:05:03.079 And that was a particular Session Config for that 71 00:05:03.079 --> 00:05:07.040 So this time, we will make another Session Config 72 00:05:07.040 --> 00:05:10.920 Go to Content Drawer, and go to what we worked with last time 73 00:05:10.920 --> 00:05:15.679 Which is Data Assets folder 74 00:05:15.679 --> 00:05:18.799 Rick click on it 75 00:05:18.799 --> 00:05:23.300 And of Miscellaneous, we will select Data assets 76 00:05:25.160 --> 00:05:29.839 And then here, where we select its parent class 77 00:05:29.839 --> 00:05:34.160 We will create another AR Session Config 78 00:05:34.160 --> 00:05:37.000 And let's click on Select 79 00:05:37.000 --> 00:05:39.880 Now, this AR Session Config 80 00:05:39.880 --> 00:05:48.079 HunetARSessionConfig_Face 81 00:05:48.079 --> 00:05:51.000 Let's name it like so 82 00:05:51.000 --> 00:05:55.040 And then the AR Session Config file we used last time 83 00:05:55.040 --> 00:06:00.320 Let's press F2 on the keyboard to add its name 84 00:06:00.320 --> 00:06:05.359 Use underbar and name it Ground 85 00:06:05.359 --> 00:06:09.839 By adjusting this, it will be easier to distinguish them 86 00:06:09.839 --> 00:06:13.289 So now, for Hunet AR Session Config Face 87 00:06:13.289 --> 00:06:15.480 In order to change its settings 88 00:06:15.480 --> 00:06:18.880 Let's double click to open Details 89 00:06:18.880 --> 00:06:21.080 And then for AR Settings 90 00:06:21.080 --> 00:06:24.959 We don't need to change much here 91 00:06:24.959 --> 00:06:28.079 But let's begin with changing its Session Type 92 00:06:28.079 --> 00:06:30.629 Here at Session Type under AR Settings 93 00:06:30.629 --> 00:06:32.600 This Session Type menu 94 00:06:32.640 --> 00:06:34.760 For now it says 'World' 95 00:06:34.760 --> 00:06:38.679 Here, 'World' means the back camera 96 00:06:38.679 --> 00:06:41.679 So let's change this to the front camera 97 00:06:41.679 --> 00:06:44.440 Which is 'Face' at this option 98 00:06:44.440 --> 00:06:47.239 So by setting Session Type to Face 99 00:06:47.239 --> 00:06:51.239 This will turn the front camera on 100 00:06:51.239 --> 00:06:54.160 So it will use the front camera to recognize the face 101 00:06:54.160 --> 00:06:57.079 And then for detection 102 00:06:57.079 --> 00:07:00.440 All the detection parts that this has as default 103 00:07:00.440 --> 00:07:02.519 We don't really need to change this 104 00:07:02.519 --> 00:07:06.119 Down here, go to 'Face AR Settings' 105 00:07:06.119 --> 00:07:10.640 Face AR Settings is about face recognition settings 106 00:07:10.640 --> 00:07:16.399 So for Tracking Direction, the direction for face tracking 107 00:07:16.399 --> 00:07:19.640 Should it be an axis value relative to the face, Face Relative 108 00:07:19.640 --> 00:07:22.000 Or Face Mirrored 109 00:07:22.000 --> 00:07:26.239 When we use the camera app 110 00:07:26.239 --> 00:07:29.600 The camera mirrors the image automatically 111 00:07:29.600 --> 00:07:34.119 I'm sure you have experience looking into a mirrored image 112 00:07:34.119 --> 00:07:37.760 So if you want this to look like 113 00:07:37.760 --> 00:07:40.559 The original image that the camera films 114 00:07:40.559 --> 00:07:43.160 Go with 'Relative' 115 00:07:43.160 --> 00:07:45.260 Or, if you rather want 116 00:07:45.260 --> 00:07:48.679 A mirrored effect to the image 117 00:07:48.679 --> 00:07:52.440 Use 'Mirrored' 118 00:07:52.440 --> 00:07:56.740 You can choose whichever one 119 00:07:56.740 --> 00:07:58.200 That you want 120 00:07:58.200 --> 00:08:03.239 For me, let's just keep the default setting, Face Relative 121 00:08:03.239 --> 00:08:07.440 And now, for 'Max Number of Tracked Faces' 122 00:08:07.440 --> 00:08:09.990 There are cases where there are 123 00:08:09.990 --> 00:08:12.839 Multiple faces existing in one image 124 00:08:12.839 --> 00:08:18.559 So this is asking how many faces it should track 125 00:08:18.559 --> 00:08:22.160 Unfortunately, for Google ARCore 126 00:08:22.160 --> 00:08:25.920 It can only recognize one face 127 00:08:25.920 --> 00:08:29.000 So whatever number you put in here 128 00:08:29.000 --> 00:08:32.960 It will only track one face in result 129 00:08:32.960 --> 00:08:38.840 So here, let's save our Data Assets 130 00:08:38.840 --> 00:08:42.000 Let's change our AR Session 131 00:08:42.000 --> 00:08:47.000 Last time we worked with the ground detection part 132 00:08:47.000 --> 00:08:49.799 And today, we will work on the face detection part 133 00:08:49.799 --> 00:08:53.280 In the next class, we will work on the image detection part 134 00:08:53.280 --> 00:08:55.080 When our application begins 135 00:08:55.080 --> 00:08:58.799 Which Session Config should be initiated? 136 00:08:58.799 --> 00:09:01.679 In order for this to be decided 137 00:09:01.679 --> 00:09:04.440 We will create a state here 138 00:09:04.440 --> 00:09:06.690 So go to Content Drawer 139 00:09:06.690 --> 00:09:11.359 At Data Assets, right click 140 00:09:11.359 --> 00:09:15.259 And under Blueprint 141 00:09:15.259 --> 00:09:19.520 Let's choose Enumeration 142 00:09:19.520 --> 00:09:21.640 Enumeration literally means 143 00:09:21.640 --> 00:09:26.320 A file where you can define enumerated constants 144 00:09:26.320 --> 00:09:28.900 So you can add various states 145 00:09:28.900 --> 00:09:31.799 In enumerated types 146 00:09:31.799 --> 00:09:35.019 Type EDetection Type 147 00:09:36.579 --> 00:09:40.280 Let's create a file called 148 00:09:40.280 --> 00:09:42.880 EDetection Type 149 00:09:42.880 --> 00:09:45.840 Let's now double click on it to open it 150 00:09:45.840 --> 00:09:50.359 At the top, there's a button called 'Add Enumerator' 151 00:09:50.359 --> 00:09:52.459 Every time you click on this 152 00:09:52.459 --> 00:09:56.119 You will get a new Display Name over here 153 00:09:56.119 --> 00:09:59.649 We will make three in total 154 00:09:59.649 --> 00:10:02.880 So we will add three Display Names 155 00:10:02.880 --> 00:10:04.840 The first one will be 156 00:10:04.840 --> 00:10:11.000 Named 'Ground Detection' 157 00:10:11.000 --> 00:10:15.700 Second, 'Face Detection' 158 00:10:15.700 --> 00:10:17.359 Let's name it like so 159 00:10:17.359 --> 00:10:23.109 And the third one, 'Image Detection' 160 00:10:23.109 --> 00:10:24.960 Let's rename it like so 161 00:10:24.960 --> 00:10:29.710 Now, after having created these three states 162 00:10:29.710 --> 00:10:32.080 Let's save 163 00:10:32.080 --> 00:10:34.259 And close the window 164 00:10:35.760 --> 00:10:39.090 So after creating an Enumeration file 165 00:10:39.090 --> 00:10:42.239 You can now create a function in a new file type 166 00:10:42.239 --> 00:10:47.969 So here at BP Hunet Player Pawn Blueprint settings menu 167 00:10:47.969 --> 00:10:49.679 Let's add a variable 168 00:10:49.679 --> 00:10:54.159 Go to VARIABLES, click on the plus button 169 00:10:54.159 --> 00:11:00.109 And then ECurrentDetection 170 00:11:00.109 --> 00:11:02.599 Let's make a new variable named that 171 00:11:02.599 --> 00:11:07.080 This function will set the current detection type 172 00:11:07.080 --> 00:11:12.890 For data type, we will use our EDetection Type 173 00:11:12.890 --> 00:11:17.039 Which is our Enumeration variable we created 174 00:11:17.039 --> 00:11:19.719 Using this data type 175 00:11:19.719 --> 00:11:22.180 This is our variable here 176 00:11:23.840 --> 00:11:28.660 Let's compile, and now at Details panel to the right 177 00:11:28.660 --> 00:11:30.760 We see 'Default Value' 178 00:11:30.760 --> 00:11:34.210 For Default Value, we will keep its default 179 00:11:34.210 --> 00:11:36.880 Which is Ground Detection 180 00:11:36.880 --> 00:11:41.180 And we will make the user click on buttons at the UI 181 00:11:41.180 --> 00:11:42.680 So that they can choose 182 00:11:42.740 --> 00:11:46.839 One of these three detection types 183 00:11:48.479 --> 00:11:52.629 So here, what we have as selected here 184 00:11:52.629 --> 00:11:56.520 Using this detection type that is selected 185 00:11:56.559 --> 00:12:02.080 Let's make the user choose one of these 186 00:12:02.080 --> 00:12:04.640 So 'Switch' 187 00:12:04.640 --> 00:12:09.240 Switch on EDetection Type, and for EDetection Type 188 00:12:09.240 --> 00:12:12.679 Let's add a new Switch statement 189 00:12:12.679 --> 00:12:17.440 For Ground Detection, for Face Detection, for Image Detection 190 00:12:17.440 --> 00:12:21.640 Since we do not know which of these three values is selected 191 00:12:21.640 --> 00:12:23.040 For these three 192 00:12:23.040 --> 00:12:26.280 Each should run its own AR Session 193 00:12:26.280 --> 00:12:30.239 For that, let's change the Exec Pin to this switch statement 194 00:12:30.239 --> 00:12:33.039 And let's bring this part a little higher 195 00:12:33.039 --> 00:12:35.320 Let's bring everything up by a little 196 00:12:35.320 --> 00:12:38.620 Here, for this switch 197 00:12:38.620 --> 00:12:43.000 Start AR Session, the Ground it had before 198 00:12:43.000 --> 00:12:48.600 Let's connect this Ground type of Start AR Session 199 00:12:48.600 --> 00:12:50.200 To this Ground Detection type 200 00:12:50.200 --> 00:12:56.679 And then, same thing, Start AR Session 201 00:12:56.679 --> 00:13:01.080 Create another node for the Start AR Session function 202 00:13:01.080 --> 00:13:06.200 And second, let's set AR Session Config as Face type 203 00:13:06.200 --> 00:13:09.800 So Session type for Face Detection 204 00:13:09.800 --> 00:13:15.280 It will connect to this here 205 00:13:15.320 --> 00:13:18.420 And now, to check if Start AR Session 206 00:13:18.420 --> 00:13:21.159 Has changed or not 207 00:13:21.159 --> 00:13:25.640 We need to check which camera is working 208 00:13:25.640 --> 00:13:29.080 Between front and back camera 209 00:13:29.080 --> 00:13:30.880 At a new scene 210 00:13:30.880 --> 00:13:33.520 For the initial creation at widget 211 00:13:33.520 --> 00:13:37.960 Let's create a new scene and a new widget 212 00:13:37.960 --> 00:13:40.860 So let's go back to the main map 213 00:13:40.860 --> 00:13:44.159 Let's create a scene 214 00:13:44.159 --> 00:13:46.009 New Level 215 00:13:46.009 --> 00:13:49.249 Same thing, Empty Level 216 00:13:49.249 --> 00:13:52.520 Let's make it empty to start with 217 00:13:52.520 --> 00:13:55.370 Here, 'Create' 218 00:13:55.370 --> 00:13:59.280 Let's create this Empty Level with nothing in it 219 00:13:59.280 --> 00:14:03.520 And let's add our Player Start to this level 220 00:14:03.520 --> 00:14:08.359 And the location for Player Start is 0, 0, 0 221 00:14:08.359 --> 00:14:10.960 Let's initialize it like so 222 00:14:10.960 --> 00:14:13.919 And now let's save this level 223 00:14:13.919 --> 00:14:17.840 Ctrl S to open this Save window 224 00:14:17.840 --> 00:14:22.679 Let's save it at our Maps folder, since it is the initial map 225 00:14:22.679 --> 00:14:26.599 Let's save it as Lobby Map 226 00:14:26.599 --> 00:14:29.200 Lobby Map 227 00:14:31.000 --> 00:14:32.440 Now at Maps folder 228 00:14:32.440 --> 00:14:35.479 We have it saved as Lobby Map as seen here 229 00:14:35.479 --> 00:14:40.760 Now, we will create a game mode that only applies to this map 230 00:14:40.760 --> 00:14:43.610 For that, go to Blueprints folder 231 00:14:43.610 --> 00:14:45.159 Right click 232 00:14:45.159 --> 00:14:48.419 And add a Blueprint Class 233 00:14:49.760 --> 00:14:52.559 Choose Game Mode Base 234 00:14:52.559 --> 00:14:59.559 Name it as BP_LobbyGameModeBase 235 00:14:59.840 --> 00:15:04.640 Let's create a file named that 236 00:15:05.239 --> 00:15:09.119 At this LobbyMap, its World Settings 237 00:15:09.119 --> 00:15:12.479 Let's change the Game Mode of this World Settings 238 00:15:12.479 --> 00:15:15.179 If you do not see a tab at all 239 00:15:15.179 --> 00:15:18.359 Called World Settings 240 00:15:18.359 --> 00:15:21.609 You can go to Window up here 241 00:15:21.609 --> 00:15:24.640 And you will see World Settings down here 242 00:15:24.640 --> 00:15:27.290 Click on World Settings button 243 00:15:27.290 --> 00:15:30.840 And you will see the World Settings window here 244 00:15:30.840 --> 00:15:35.799 At World Settings tab, look at Game Mode Override 245 00:15:35.799 --> 00:15:37.729 It is set as None now 246 00:15:37.729 --> 00:15:40.940 Open this and BP_LobbyGameMode 247 00:15:40.940 --> 00:15:45.920 Let's select BP_LobbyGameModeBase 248 00:15:47.799 --> 00:15:50.999 Like so, for the rule called Game Mode Base 249 00:15:50.999 --> 00:15:53.679 A class that is designated for this rule 250 00:15:53.679 --> 00:15:58.159 This can be set separately for each level 251 00:15:58.200 --> 00:16:01.200 For this Game Mode, when we first begin 252 00:16:01.200 --> 00:16:03.760 Here, we will add to this empty space 253 00:16:03.760 --> 00:16:05.760 A UI 254 00:16:05.760 --> 00:16:07.159 We will have a UI image here 255 00:16:07.159 --> 00:16:12.679 For that, go to Content Drawer, right click 256 00:16:12.679 --> 00:16:15.229 Select New Folder 257 00:16:15.229 --> 00:16:16.840 And let's create a new folder 258 00:16:16.840 --> 00:16:21.320 Let's name the folder as 'UI' 259 00:16:21.320 --> 00:16:25.559 For this UI folder, right click 260 00:16:25.559 --> 00:16:29.400 Go to User Interface, select Widget Blueprint 261 00:16:29.400 --> 00:16:33.719 And we will create a graphic UI file called Widget Blueprint 262 00:16:33.719 --> 00:16:36.799 Create a Widget Blueprint file 263 00:16:36.799 --> 00:16:38.949 It only has one parent class, right? 264 00:16:38.949 --> 00:16:43.039 Let's now select this User Widget 265 00:16:43.039 --> 00:16:48.000 So to mean Widget Blueprint, we will say WBP 266 00:16:48.000 --> 00:16:51.500 _LobbyWidget 267 00:16:51.500 --> 00:16:54.679 This will be the name for this widget 268 00:16:54.679 --> 00:16:57.599 Open Lobby Widget settings window 269 00:16:57.599 --> 00:17:00.849 First, we need a canvas to have our widget on 270 00:17:00.849 --> 00:17:02.760 It's like a piece of paper to start painting 271 00:17:02.760 --> 00:17:06.110 So to the left, at Palette 272 00:17:06.110 --> 00:17:11.080 Let's bring in a component called Canvas Panel 273 00:17:11.080 --> 00:17:15.880 Let's put this Canvas Panel to this LobbyWidget 274 00:17:15.880 --> 00:17:18.930 Then, as its top route component 275 00:17:18.930 --> 00:17:22.080 It will have a Canvas Panel 276 00:17:22.080 --> 00:17:24.930 This green box here is 277 00:17:24.930 --> 00:17:27.730 The screen to be seen 278 00:17:27.730 --> 00:17:31.760 For the actual widget, like a piece of paper 279 00:17:31.760 --> 00:17:34.910 Down here we have its resolution 280 00:17:34.910 --> 00:17:36.800 We have its standard resolution 281 00:17:36.800 --> 00:17:40.950 Nowadays, the most popularly used resolution type is 282 00:17:40.950 --> 00:17:43.280 HD resolution 283 00:17:43.280 --> 00:17:45.800 So its standard resolution is the HD one 284 00:17:45.800 --> 00:17:49.400 Which is 1920px width and 1080px length 285 00:17:49.400 --> 00:17:51.239 That's the standard resolution 286 00:17:51.239 --> 00:17:53.389 In order to set for this standard resolution 287 00:17:53.389 --> 00:17:57.439 Go to the bottom right of this canvas 288 00:17:57.439 --> 00:18:00.599 And drag this cursor icon 289 00:18:04.040 --> 00:18:07.840 And let's zoom out as much as possible 290 00:18:07.840 --> 00:18:13.640 Let's fit this to the HD resolution, or 1920x1080 291 00:18:13.640 --> 00:18:15.840 And once we have it 292 00:18:15.840 --> 00:18:19.400 It will say 1920x1080 at the bottom here 293 00:18:19.400 --> 00:18:21.250 This is the standard resolution 294 00:18:21.250 --> 00:18:24.100 So the scale is also 1 295 00:18:25.520 --> 00:18:28.680 Now, let's fit some things into this 296 00:18:28.680 --> 00:18:34.739 First, for this widget, we will see some buttons 297 00:18:36.680 --> 00:18:40.330 So drag in a button component 298 00:18:40.330 --> 00:18:43.200 And paste into our cnavas panel 299 00:18:45.400 --> 00:18:47.600 We need three buttons in total 300 00:18:47.600 --> 00:18:49.959 That's because our choice of types 301 00:18:49.959 --> 00:18:52.459 Include three different direction types 302 00:18:52.459 --> 00:18:54.319 So we will have three buttons 303 00:18:54.319 --> 00:18:57.569 The easiest way is to complete a button 304 00:18:57.569 --> 00:19:01.880 And copy and paste that for others 305 00:19:01.880 --> 00:19:04.880 So now, for this button 306 00:19:04.880 --> 00:19:06.190 Let's set its anchor 307 00:19:06.190 --> 00:19:07.859 Anchor means its desired location 308 00:19:07.859 --> 00:19:10.769 And since we will be setting the buttons to the center 309 00:19:10.769 --> 00:19:12.619 Its desired location or anchor 310 00:19:12.619 --> 00:19:15.520 Its anchor should also be at the center of the canvas 311 00:19:15.520 --> 00:19:18.220 Then, this pin icon 312 00:19:18.220 --> 00:19:20.959 Is now moved to the center as seen here 313 00:19:20.959 --> 00:19:23.209 This is now our desired point 314 00:19:23.209 --> 00:19:27.959 And for this point, let's set X and Y positions 315 00:19:27.959 --> 00:19:32.209 To the default, which is 0, 0 316 00:19:32.209 --> 00:19:37.040 Then the top left of the button will fit on the anchor pin 317 00:19:37.040 --> 00:19:39.540 But if we are to set it to the center 318 00:19:39.540 --> 00:19:43.790 It is easier to have our anchor pin set on the center of the component 319 00:19:43.790 --> 00:19:46.959 When we are to set its location 320 00:19:46.959 --> 00:19:50.609 So go to Alignment here 321 00:19:50.609 --> 00:19:54.009 And type 0.5 322 00:19:54.009 --> 00:19:58.040 Which is the middle point between horizontal 0 to 1, 0.5 323 00:19:58.040 --> 00:20:00.140 And also between the vertical 0 to 1 324 00:20:00.140 --> 00:20:02.640 Add its middle value, 0.5 325 00:20:02.640 --> 00:20:05.790 Then, like so, in the middle of its vertical and horizontal 326 00:20:05.790 --> 00:20:09.239 We will have the anchor set in the center 327 00:20:09.280 --> 00:20:13.080 Now, we will make the button bigger 328 00:20:13.080 --> 00:20:20.160 Let's set it as around 400x100 329 00:20:20.160 --> 00:20:24.270 Now, we need some letters on the button 330 00:20:24.270 --> 00:20:28.220 For that, let's add Text component as 331 00:20:28.220 --> 00:20:31.359 The child object of our Button component 332 00:20:31.359 --> 00:20:34.659 So for this Text component 333 00:20:34.659 --> 00:20:38.760 Here, its font size 334 00:20:39.119 --> 00:20:43.319 Font size, around 40 335 00:20:43.319 --> 00:20:46.199 Let's set it as around 40 pixels 336 00:20:46.199 --> 00:20:50.299 And the content of the text, first of all 337 00:20:50.299 --> 00:20:54.439 Let's call it 'Ground Type' 338 00:20:54.439 --> 00:20:57.839 The text is too hard against the button 339 00:20:57.839 --> 00:21:00.559 So let's add some shadow 340 00:21:00.579 --> 00:21:04.399 Let's set the shadow 341 00:21:04.399 --> 00:21:09.280 As around this dark grey color 342 00:21:09.280 --> 00:21:14.630 Let's add around 0.6 for its Alpha value 343 00:21:14.630 --> 00:21:17.630 So it has some shadow, but it's not enough 344 00:21:17.630 --> 00:21:21.010 So let's set the shadow size as around 3 345 00:21:22.250 --> 00:21:26.200 Around three, for all width, length and height 346 00:21:26.200 --> 00:21:27.950 Let's add around 3 347 00:21:27.950 --> 00:21:32.000 Now we see some depth to the text 348 00:21:32.520 --> 00:21:37.199 Now, in order for the button color to pop 349 00:21:37.400 --> 00:21:41.100 Let's go to Background Color to the right 350 00:21:41.100 --> 00:21:44.050 And let's make it a blue button 351 00:21:44.050 --> 00:21:46.800 So let's set its color like so 352 00:21:46.800 --> 00:21:49.000 Click 'Okay' 353 00:21:49.000 --> 00:21:53.200 When you change the button color, you must always 354 00:21:53.200 --> 00:21:55.640 Have this 'Button' component selected 355 00:21:55.640 --> 00:21:57.240 Before you change the color 356 00:21:57.240 --> 00:22:01.520 If you change the color when 'Text' is selected 357 00:22:01.520 --> 00:22:04.770 It will only change the font color 358 00:22:04.770 --> 00:22:08.640 So the button name for now is 359 00:22:08.640 --> 00:22:14.280 Button_Ground 360 00:22:14.280 --> 00:22:16.820 Let's set it as that 361 00:22:19.920 --> 00:22:26.199 Next, select this Ground Button and press 362 00:22:26.199 --> 00:22:30.949 Ctrl D to make a copy 363 00:22:30.949 --> 00:22:34.099 For this second button 364 00:22:34.099 --> 00:22:37.400 Let's put it right below Ground Type 365 00:22:37.400 --> 00:22:39.600 And for the font here 366 00:22:39.600 --> 00:22:43.150 Let's say 'Face Type' 367 00:22:43.150 --> 00:22:46.280 So the text is now 'Face Type' 368 00:22:46.280 --> 00:22:50.630 And then, the button name 369 00:22:50.630 --> 00:22:52.330 Its button name 370 00:22:52.330 --> 00:22:57.139 Let's say 'Button_Face' 371 00:23:00.239 --> 00:23:03.889 Select Face again 372 00:23:03.889 --> 00:23:06.640 And Ctrl D to make another copy 373 00:23:06.640 --> 00:23:11.450 This third button here 374 00:23:11.450 --> 00:23:18.030 Let's call its name as 'Image' 375 00:23:18.030 --> 00:23:22.390 And select the text inside, and its content 376 00:23:22.390 --> 00:23:24.680 Instead of Face Type 377 00:23:24.680 --> 00:23:29.920 Let's set it as 'Image Type' 378 00:23:29.920 --> 00:23:32.820 Then you get these three buttons 379 00:23:32.820 --> 00:23:34.670 Notice how they are not aligned 380 00:23:34.670 --> 00:23:36.119 They are a little out of place 381 00:23:36.119 --> 00:23:38.819 So we will group all these three together 382 00:23:38.819 --> 00:23:43.319 So start with Ground, press Shift 383 00:23:43.319 --> 00:23:46.880 And select Image, which will select all three 384 00:23:46.880 --> 00:23:50.100 So here, right click 385 00:23:50.100 --> 00:23:52.600 And at the bottom, 'Wrap With' 386 00:23:52.600 --> 00:23:54.560 So it will be wrapped with something 387 00:23:54.560 --> 00:23:57.560 Wrapped with, and at the bottom 388 00:23:57.560 --> 00:24:02.000 Let's select this Vertical Box 389 00:24:02.040 --> 00:24:05.290 Then, this component called Vertical Box 390 00:24:05.290 --> 00:24:07.690 It will have all these three buttons 391 00:24:07.690 --> 00:24:11.820 As its child objects; so this becomes a parent object 392 00:24:13.880 --> 00:24:16.030 So for this Vertical Box 393 00:24:16.030 --> 00:24:18.680 While it has all three buttons 394 00:24:18.680 --> 00:24:22.330 There needs some space between buttons 395 00:24:22.330 --> 00:24:24.319 So let's make it big enough for that 396 00:24:24.319 --> 00:24:26.719 For size X 397 00:24:26.719 --> 00:24:29.619 Let's set it as 400, which is same as the button's 398 00:24:29.619 --> 00:24:33.319 For size Y, let's make it longer 399 00:24:33.319 --> 00:24:35.389 Since we need three buttons of size 100 each 400 00:24:35.389 --> 00:24:37.169 Let's start with 300 401 00:24:37.169 --> 00:24:39.869 And to give 20 for each spacing 402 00:24:39.869 --> 00:24:42.400 So between two buttons we give around 20 403 00:24:42.400 --> 00:24:46.930 So for three, we need 60, so around 360 404 00:24:46.930 --> 00:24:50.720 Let's set 360 for our height, or size Y 405 00:24:52.680 --> 00:24:56.600 Now, select the three buttons 406 00:24:56.600 --> 00:24:59.050 When we have all three buttons selected 407 00:24:59.050 --> 00:25:04.199 Let's go to Size here and change from Auto to Fill 408 00:25:04.199 --> 00:25:05.949 And on top, where it says Padding 409 00:25:05.949 --> 00:25:10.049 For Padding, let's use 0 for horizontal and 410 00:25:10.049 --> 00:25:13.439 Around 10 pixels for the vertical padding 411 00:25:13.439 --> 00:25:16.839 Now, like so, between two buttons 412 00:25:16.839 --> 00:25:21.680 We get around 10 spacing 413 00:25:21.680 --> 00:25:24.480 So that's how we changed it 414 00:25:24.480 --> 00:25:27.710 Like so, we have all buttons 415 00:25:27.710 --> 00:25:30.839 Aligned nicely at Vertical Box 416 00:25:30.839 --> 00:25:33.489 Next, in order for our Vertical Box 417 00:25:33.489 --> 00:25:36.759 To move downward, or to change it position Y value 418 00:25:36.759 --> 00:25:40.560 Let's bring it down by around 50 419 00:25:40.560 --> 00:25:43.160 So for position Y 420 00:25:43.160 --> 00:25:48.160 Let's add the value 50 421 00:25:48.160 --> 00:25:51.560 And now, in order for the user to know what they are choosing 422 00:25:51.560 --> 00:25:53.560 Let's add another text on top 423 00:25:53.560 --> 00:25:58.690 Add a text box on this canvas 424 00:25:58.690 --> 00:26:01.160 And for this text, set its anchor 425 00:26:01.160 --> 00:26:04.340 At the center of the screen, and for Alignment 426 00:26:04.340 --> 00:26:08.400 Let's set it as 0.5, 0.5, with the center of the screen 427 00:26:09.839 --> 00:26:12.539 So when we have it back to 0, 0 428 00:26:12.539 --> 00:26:15.960 Let's drag on our position Y value 429 00:26:17.800 --> 00:26:20.550 Then we see our text box 430 00:26:20.550 --> 00:26:22.880 That has moved upward like so 431 00:26:22.880 --> 00:26:28.839 Let's keep it at around -300 432 00:26:28.839 --> 00:26:33.439 And its font size, around 70 433 00:26:33.439 --> 00:26:36.479 And let's align the font to the center 434 00:26:36.479 --> 00:26:39.199 So its Justification, set it as center 435 00:26:39.199 --> 00:26:42.239 Click here, so that it aligns to the center 436 00:26:42.239 --> 00:26:45.789 After that, for this text, let's type 437 00:26:45.789 --> 00:26:52.560 'Select Detection Type' 438 00:26:52.560 --> 00:26:56.460 So this will be what it says, to ask for selection 439 00:26:56.460 --> 00:26:58.460 Now, for font color 440 00:26:58.460 --> 00:27:01.280 Let's make it yellow 441 00:27:01.280 --> 00:27:04.380 So we changed the font color 442 00:27:04.380 --> 00:27:08.680 Now its size should fit in the font 443 00:27:08.680 --> 00:27:13.480 So it should be around 800 444 00:27:13.480 --> 00:27:16.040 Or even around 100 445 00:27:16.040 --> 00:27:20.079 And for height, since that of font is 70, it should be bigger 446 00:27:20.079 --> 00:27:26.319 90, 100, let's say 100 447 00:27:26.319 --> 00:27:30.769 Or let's even say 110 448 00:27:30.769 --> 00:27:34.599 So this is what we see on the screen 449 00:27:34.599 --> 00:27:39.089 It looks like a landscape view 450 00:27:39.089 --> 00:27:41.039 But when we actually have it there 451 00:27:41.039 --> 00:27:43.280 Since its anchor is set to the center 452 00:27:43.280 --> 00:27:45.670 Even if it is vertically long now 453 00:27:45.670 --> 00:27:50.579 It will be reconfigured with that scale 454 00:27:50.579 --> 00:27:54.359 Let's compile and save 455 00:27:56.599 --> 00:27:59.949 Now that we have the widget 456 00:27:59.949 --> 00:28:01.849 Let's have its actual part 457 00:28:01.849 --> 00:28:04.140 Run on the screen 458 00:28:05.880 --> 00:28:09.720 So Game Mode, what we made before 459 00:28:09.720 --> 00:28:12.030 Lobby Game Mode Base 460 00:28:12.030 --> 00:28:15.219 Let's double click on it to run 461 00:28:17.539 --> 00:28:20.619 So when it first begins, at Begin Play 462 00:28:20.619 --> 00:28:24.839 We need the widget spawned there, so let's code it 463 00:28:24.839 --> 00:28:29.880 At Begin Play, drag on its Execution Node 464 00:28:29.880 --> 00:28:35.069 Search for Create Widget 465 00:28:35.069 --> 00:28:37.419 And you will see Create Widget Node 466 00:28:37.419 --> 00:28:41.160 With this Create Widget Node 467 00:28:41.160 --> 00:28:45.860 Here, this WVP_LobbyWidget that we made before 468 00:28:45.860 --> 00:28:47.560 WVP_LobbyWidget file 469 00:28:47.560 --> 00:28:51.520 Let's set it so that it creates that 470 00:28:51.520 --> 00:28:53.920 So this created instance 471 00:28:53.920 --> 00:28:56.220 In order for it to show on the screen 472 00:28:56.220 --> 00:28:58.760 Add to Viewport 473 00:28:58.760 --> 00:29:01.740 This will move it to the screen 474 00:29:04.460 --> 00:29:07.460 Let's now compile and save 475 00:29:07.460 --> 00:29:09.510 Now, let's run this 476 00:29:09.510 --> 00:29:12.640 Now we see the UI pop up like so 477 00:29:12.640 --> 00:29:16.410 For now, since we have nothing connected to the buttons 478 00:29:16.410 --> 00:29:19.040 It's now time to connect the button functions 479 00:29:19.040 --> 00:29:21.940 Here, even if we press on that button 480 00:29:21.940 --> 00:29:23.290 Detection Type 481 00:29:23.290 --> 00:29:26.790 This Detection Type that we created before 482 00:29:26.790 --> 00:29:28.959 Even if we change that type 483 00:29:29.040 --> 00:29:33.240 When we move between levels or maps 484 00:29:33.240 --> 00:29:36.840 For example, from Lobby map to Main map 485 00:29:36.840 --> 00:29:38.959 All that data will be lost 486 00:29:38.959 --> 00:29:43.109 So in order to save that data 487 00:29:43.109 --> 00:29:46.880 We need a class that will keep these 488 00:29:46.880 --> 00:29:49.130 So, at Blueprint folder 489 00:29:49.130 --> 00:29:50.730 Right click 490 00:29:50.730 --> 00:29:53.959 Create another Blueprint class 491 00:29:53.959 --> 00:29:56.959 Now we need Game Instance 492 00:29:56.959 --> 00:29:59.309 We need to create a Game Instance 493 00:29:59.309 --> 00:30:01.079 Since it doesn't have it here 494 00:30:01.079 --> 00:30:04.579 Click on ALL CLASSES here 495 00:30:04.579 --> 00:30:07.459 Open the search tab and 496 00:30:07.459 --> 00:30:11.319 Search for 'Game Instance' 497 00:30:11.319 --> 00:30:13.769 And we have a Game Instance class 498 00:30:13.769 --> 00:30:17.800 So select Game Instance class 499 00:30:17.800 --> 00:30:21.800 So select it and name this new Blueprint file 500 00:30:21.800 --> 00:30:26.679 As BP_ARGameInstance 501 00:30:31.319 --> 00:30:35.169 For Game Instance, we will create a variable 502 00:30:35.169 --> 00:30:37.900 A variable here will be 503 00:30:37.900 --> 00:30:44.700 Selected Detection Type 504 00:30:44.700 --> 00:30:47.719 That's the name for this new variable 505 00:30:47.719 --> 00:30:49.419 Selected Detection Type 506 00:30:49.419 --> 00:30:54.669 Data type, EDetectionType 507 00:30:54.669 --> 00:30:58.179 That variable will be our data type 508 00:30:59.680 --> 00:31:01.480 Compile 509 00:31:01.480 --> 00:31:05.780 Once you compile, you'll get this default value at this Details panel 510 00:31:05.780 --> 00:31:10.119 Set its default type as Ground Detection 511 00:31:10.119 --> 00:31:12.869 And let's save 512 00:31:12.869 --> 00:31:15.419 Now close the window 513 00:31:15.419 --> 00:31:17.119 Project Settings 514 00:31:17.119 --> 00:31:21.419 Edit, Project Settings 515 00:31:21.419 --> 00:31:24.239 And go to Maps & Modes 516 00:31:24.239 --> 00:31:27.989 At Maps & Modes, go to the very bottom 517 00:31:27.989 --> 00:31:31.289 And this Game Instance class, let's change it to 518 00:31:31.289 --> 00:31:34.600 What we just made, BP_APGameInstance 519 00:31:36.920 --> 00:31:39.310 And then, from what we made 520 00:31:39.310 --> 00:31:42.959 Let's go back to our widget 521 00:31:42.959 --> 00:31:48.659 Select Ground Type button, and in order to 522 00:31:48.659 --> 00:31:52.359 Connect functions to run when the component is clicked 523 00:31:52.359 --> 00:31:55.259 At the very bottom, at Events, OnClicked 524 00:31:55.259 --> 00:31:58.340 Click on the plus button for OnClicked 525 00:32:00.319 --> 00:32:03.459 When this button is clicked, the first thing is 526 00:32:03.459 --> 00:32:05.880 To bring in Game Instance 527 00:32:05.880 --> 00:32:11.860 So to get that Game Instance 528 00:32:11.860 --> 00:32:14.110 Get Game Instance 529 00:32:14.110 --> 00:32:18.319 Add a node called Get Game Instance 530 00:32:18.319 --> 00:32:22.669 And this Game Instance we currently have 531 00:32:22.669 --> 00:32:28.079 Let's change it to 'Cast to BP_ARGameInstance' 532 00:32:28.079 --> 00:32:30.429 Let's change that class 533 00:32:30.429 --> 00:32:36.160 And then at BP_ARGameInstance 534 00:32:36.160 --> 00:32:40.040 This SelectedDetectionType 535 00:32:40.040 --> 00:32:41.620 Let's change this value here 536 00:32:41.620 --> 00:32:43.959 To do so, we need Set 537 00:32:43.959 --> 00:32:48.209 Let's connect Set Selected Detection Type to the node 538 00:32:48.209 --> 00:32:50.659 Now, connect all the Execution panels 539 00:32:54.439 --> 00:32:58.769 Since we just clicked on Ground button 540 00:32:58.769 --> 00:33:01.189 When we click on Ground button, its Detection Type 541 00:33:01.189 --> 00:33:04.920 Will be set as Ground Detection 542 00:33:04.959 --> 00:33:06.459 And then, same thing 543 00:33:06.459 --> 00:33:09.229 Back to Designer panel 544 00:33:09.249 --> 00:33:11.479 At Deisgner 545 00:33:11.479 --> 00:33:14.659 The second, Face Type button, its OnlClick 546 00:33:14.659 --> 00:33:18.520 At the bottom, at OnClick event, click on the plus button 547 00:33:21.079 --> 00:33:26.489 For OnClicked, this same part with the same nodes 548 00:33:26.489 --> 00:33:31.079 We will Ctrl+C and Ctrl+V to copy and paste 549 00:33:31.079 --> 00:33:32.629 Let's now connect the Execution Pin 550 00:33:32.629 --> 00:33:35.279 And here, its Detection Type 551 00:33:35.279 --> 00:33:41.139 Instead of Ground Detection, let's make it Face Detection 552 00:33:44.839 --> 00:33:48.289 Finally for Image Type button 553 00:33:48.289 --> 00:33:50.729 Click on the OnClick button 554 00:33:50.749 --> 00:33:54.049 And for OnClick event for the button image 555 00:33:54.049 --> 00:33:56.680 Same thing, copy these three here 556 00:33:56.680 --> 00:34:00.030 Ctrl+C and Ctrl+V to copy and paste 557 00:34:00.030 --> 00:34:02.380 And connect the Execution Pin 558 00:34:02.380 --> 00:34:04.680 And then for Detection Type 559 00:34:04.680 --> 00:34:08.040 This time, let's change it to Image Detection 560 00:34:08.040 --> 00:34:10.199 And then compile, save 561 00:34:11.879 --> 00:34:16.259 Now, when this Game Mode button is clicked 562 00:34:16.259 --> 00:34:19.879 At Game Instance 563 00:34:19.879 --> 00:34:22.259 Its Detection Type will be saved 564 00:34:22.259 --> 00:34:27.000 And there's something to do for all these three 565 00:34:27.000 --> 00:34:30.550 For all of them, we need to change their level 566 00:34:30.550 --> 00:34:35.560 Let's try Open Level(By Name) 567 00:34:35.560 --> 00:34:38.410 So here, the level name is 568 00:34:38.410 --> 00:34:40.760 Since we're going to the main map 569 00:34:40.760 --> 00:34:42.919 Let's name it MainMap 570 00:34:42.919 --> 00:34:47.560 And let's copy the original name using Ctrl+C 571 00:34:47.560 --> 00:34:51.310 And Ctrl+V to paste 572 00:34:51.310 --> 00:34:55.560 Keep copying and pasting the nodes with Ctrl+C and Ctrl+V 573 00:34:55.560 --> 00:34:59.310 So that for each Set function 574 00:34:59.310 --> 00:35:02.600 Has the Execution Pin connected like so 575 00:35:02.600 --> 00:35:04.800 And then compile and save 576 00:35:04.820 --> 00:35:07.600 Now, this widget function is complete 577 00:35:10.520 --> 00:35:12.270 Now, let's say that 578 00:35:12.270 --> 00:35:15.080 We clicked on the button and went to the main map 579 00:35:15.080 --> 00:35:19.260 Double click on MainMap to open it 580 00:35:19.260 --> 00:35:23.750 At MainMap, something we've been working on 581 00:35:23.750 --> 00:35:25.600 BP_Hunet Player Pawn 582 00:35:25.600 --> 00:35:29.600 Double click and open its settings again 583 00:35:29.600 --> 00:35:33.330 When it reads this Current Detection 584 00:35:33.330 --> 00:35:37.600 Before it does so, DetectionType at Game Instance 585 00:35:37.600 --> 00:35:40.120 Let's move it to this variable 586 00:35:40.120 --> 00:35:45.120 Before ReadyForAR 587 00:35:45.140 --> 00:35:47.990 Let's push it a little to the back 588 00:35:47.990 --> 00:35:51.600 So before this, something we need it 589 00:35:51.600 --> 00:35:54.980 Just like before, Get Game Instance 590 00:35:54.980 --> 00:35:57.280 Get the current Get Instance value 591 00:35:57.280 --> 00:35:59.440 And we will cast that 592 00:35:59.440 --> 00:36:04.420 Cast To BP_ARGameInstance 593 00:36:04.420 --> 00:36:08.740 So we will connect the Execution Pin here 594 00:36:08.740 --> 00:36:11.600 Once the casting is successful 595 00:36:11.600 --> 00:36:14.600 Let's push these nodes a little further 596 00:36:14.600 --> 00:36:17.500 Then there is the Game Instance value 597 00:36:17.500 --> 00:36:19.250 And for this Game Instance 598 00:36:19.250 --> 00:36:23.600 We'll use Get for Selected Detection Type 599 00:36:23.600 --> 00:36:27.600 Get Selected Detection Type 600 00:36:27.600 --> 00:36:32.940 And this value, Set ECurrent Decetion 601 00:36:37.300 --> 00:36:41.600 The value set in the previous UI for Game Instance 602 00:36:41.600 --> 00:36:44.990 For this CurrentDetection variable 603 00:36:44.990 --> 00:36:48.260 Let's copy it in there 604 00:36:48.260 --> 00:36:52.280 And then the saved result 605 00:36:52.280 --> 00:36:53.930 This Current Detection 606 00:36:53.930 --> 00:36:57.380 You can now remove this node and connect it here instead 607 00:36:57.380 --> 00:36:59.600 And the effect is 608 00:36:59.600 --> 00:37:02.750 If the value that came from Game Instance is 609 00:37:02.750 --> 00:37:04.460 Ground Detection 610 00:37:04.460 --> 00:37:08.120 Then the top one, Start AR Session is run 611 00:37:08.120 --> 00:37:11.050 And for Face Detection, the bottom one 612 00:37:11.050 --> 00:37:13.600 Start AR Session will be run 613 00:37:13.600 --> 00:37:16.400 Since there is no image 614 00:37:16.400 --> 00:37:18.320 Because we are working on it the next class 615 00:37:18.320 --> 00:37:20.760 Let's just leave it empty for now 616 00:37:23.820 --> 00:37:28.600 And then same thing at this Event Tick 617 00:37:28.600 --> 00:37:30.700 Based on Detection Type 618 00:37:30.700 --> 00:37:32.600 What this runs will be different 619 00:37:32.600 --> 00:37:37.200 First, get Current Detection variable 620 00:37:37.220 --> 00:37:40.140 And from the Current Detectino value 621 00:37:40.140 --> 00:37:43.880 Switch on, this Detection Type, for each 622 00:37:43.880 --> 00:37:47.820 It will run different things when we connect it like so 623 00:37:47.820 --> 00:37:51.240 For Spawn Actor To Ground variable that we worked on last class 624 00:37:51.240 --> 00:37:54.534 It will be run for Ground Detection 625 00:37:54.534 --> 00:37:57.814 Adding Image and Effect 626 00:37:58.674 --> 00:38:01.840 Let's start implementing 627 00:38:04.280 --> 00:38:07.100 Functions for Face Detection 628 00:38:07.100 --> 00:38:11.600 Last time, when we worked on Ground Detection 629 00:38:11.600 --> 00:38:14.600 Remember the function node we used? 630 00:38:14.600 --> 00:38:20.000 Get All AR Geometry 631 00:38:20.000 --> 00:38:23.300 Geometry is for ground detection 632 00:38:23.300 --> 00:38:26.400 But we could assign different types for detection 633 00:38:26.400 --> 00:38:28.840 So now, let's use this thing at the bottom 634 00:38:28.840 --> 00:38:31.940 Get All AR Geometries By Class 635 00:38:31.940 --> 00:38:36.220 Let's create this node 636 00:38:36.220 --> 00:38:38.810 This class that we are trying to detect 637 00:38:38.810 --> 00:38:40.220 Is type Face 638 00:38:40.220 --> 00:38:47.280 So we will go with ARFaceGeometry 639 00:38:47.280 --> 00:38:51.740 Of the values we got, this value 640 00:38:51.740 --> 00:38:55.700 Or Length 641 00:38:55.700 --> 00:38:58.400 Should be greater than 0 642 00:38:58.400 --> 00:39:01.220 So Greater, at least one 643 00:39:01.220 --> 00:39:03.500 So that means there is a face that has been detected 644 00:39:03.520 --> 00:39:06.720 However, since our Max for face detection 645 00:39:06.720 --> 00:39:08.680 Is one 646 00:39:08.680 --> 00:39:11.200 It is impossible to detect more than one face 647 00:39:11.200 --> 00:39:13.800 So either greater than 0 or is 1 648 00:39:13.800 --> 00:39:16.600 They will result in the same thing 649 00:39:16.600 --> 00:39:19.600 If greater than 0, it has something detected 650 00:39:19.600 --> 00:39:22.600 Then, for its branch 651 00:39:22.600 --> 00:39:24.000 If greater than 0 652 00:39:24.000 --> 00:39:26.360 Meaning, if it detected at least one thing 653 00:39:26.360 --> 00:39:28.810 If it has at least once face detected 654 00:39:28.810 --> 00:39:31.480 Meaning, for True 655 00:39:36.040 --> 00:39:41.800 Using that Face ARGeometry that we just got 656 00:39:41.800 --> 00:39:44.380 Get, the no.0 one 657 00:39:44.380 --> 00:39:47.220 The first one, since it only detects one face 658 00:39:47.220 --> 00:39:48.420 The first one 659 00:39:48.420 --> 00:39:51.260 No.0, for this one 660 00:39:51.260 --> 00:39:56.160 Get Local To World Transform 661 00:39:56.160 --> 00:39:57.710 It will get that World coordinate information 662 00:39:57.710 --> 00:39:59.620 The World coordinate for the detected face 663 00:39:59.620 --> 00:40:02.600 Using Get Local To WorldTransform 664 00:40:02.600 --> 00:40:04.300 So at this point 665 00:40:04.300 --> 00:40:08.600 Let's add something like a mask 666 00:40:08.600 --> 00:40:12.180 So we need to create a mask for this 667 00:40:12.180 --> 00:40:15.170 For this image, you can use the file 668 00:40:15.170 --> 00:40:17.360 That I provided in advance 669 00:40:18.740 --> 00:40:24.440 The mask image, use Ctrl+X to cut 670 00:40:24.440 --> 00:40:27.520 And at our Unreal Project 671 00:40:27.520 --> 00:40:31.600 At our HunetAR folder, Content folder 672 00:40:31.600 --> 00:40:34.100 Textures folder 673 00:40:34.100 --> 00:40:37.280 Ctrl+V to paste 674 00:40:37.280 --> 00:40:40.200 So this is Finder for Windows 675 00:40:40.200 --> 00:40:43.600 And back to our Editor 676 00:40:43.600 --> 00:40:45.400 It says that we have a new image 677 00:40:45.400 --> 00:40:46.820 And it asks if I want to import it 678 00:40:46.820 --> 00:40:49.360 So say Import 679 00:40:49.360 --> 00:40:51.780 So let's click on 'Import' 680 00:40:51.780 --> 00:40:54.740 And then it says 681 00:40:54.740 --> 00:40:57.900 This file has been modified to fit Unreal 682 00:40:57.900 --> 00:41:02.660 So here, let's create an actor 683 00:41:04.140 --> 00:41:07.420 So open Content Drawer 684 00:41:07.420 --> 00:41:10.040 Right click on Blueprint Class 685 00:41:10.040 --> 00:41:11.860 To create a new Blueprint class 686 00:41:11.860 --> 00:41:16.260 Let's create it in type Actor 687 00:41:16.260 --> 00:41:20.840 BP_MaskActor 688 00:41:20.840 --> 00:41:22.980 That will be the name for this Blueprint file 689 00:41:24.420 --> 00:41:27.500 Double click to open the window 690 00:41:27.520 --> 00:41:30.600 Basically, we do not need anything else here 691 00:41:30.600 --> 00:41:34.360 We need one Plane Mesh and one Pot Mesh 692 00:41:34.360 --> 00:41:38.780 Plane, click on Add here 693 00:41:38.780 --> 00:41:42.600 And add a new Plane Mesh 694 00:41:42.600 --> 00:41:44.920 Static Mesh 695 00:41:44.920 --> 00:41:49.497 Plane Mesh, the image is showing here now 696 00:41:49.497 --> 00:41:50.737 On top of this 697 00:41:50.737 --> 00:41:52.870 For that 698 00:41:52.870 --> 00:41:55.600 In order to paste the image here 699 00:41:55.600 --> 00:41:59.220 Go to Textures folder, the mask image we imported 700 00:41:59.220 --> 00:42:01.600 Double click on the mask file to open 701 00:42:01.600 --> 00:42:03.800 And its texture group is set as World 702 00:42:03.800 --> 00:42:05.940 Since we are using it for UI 703 00:42:05.940 --> 00:42:09.600 Let's change it to UI 704 00:42:09.600 --> 00:42:12.620 And we will apply Alpha values or transparency value 705 00:42:14.600 --> 00:42:16.600 And back to this window 706 00:42:16.600 --> 00:42:19.180 See how Alpha value has been applied? 707 00:42:19.180 --> 00:42:22.380 For mask, right click 708 00:42:22.380 --> 00:42:27.160 And select Create Materials 709 00:42:27.160 --> 00:42:30.460 And we get a Material file 710 00:42:30.460 --> 00:42:33.260 The name will be M_Mask 711 00:42:33.260 --> 00:42:35.080 Let's create a file with that name 712 00:42:35.080 --> 00:42:39.280 Double click on M_Mask to open 713 00:42:42.460 --> 00:42:45.960 Push its texture sample to the left 714 00:42:45.960 --> 00:42:48.520 For this M_Mask 715 00:42:48.520 --> 00:42:51.600 For this Material default setting node 716 00:42:51.600 --> 00:42:54.440 To the left, at Details 717 00:42:54.440 --> 00:42:57.807 It says 'Blend Mode' 718 00:42:57.807 --> 00:43:00.340 For Blend Mode, Opaque is 719 00:43:00.340 --> 00:43:03.460 Only for showing opaque image 720 00:43:03.460 --> 00:43:06.157 In order to allow for transparent images 721 00:43:06.157 --> 00:43:09.717 Let's change it to Translucent 722 00:43:09.717 --> 00:43:12.100 So we have Translucent 723 00:43:12.100 --> 00:43:16.270 And this will add Opacity here 724 00:43:16.270 --> 00:43:17.660 Rather, it will activate it 725 00:43:17.660 --> 00:43:21.610 Here, Alpha value for transparency 726 00:43:21.610 --> 00:43:24.260 Let's connect the Alpha node to Exec Node 727 00:43:24.260 --> 00:43:26.080 To Opacity 728 00:43:26.080 --> 00:43:29.400 And then save 729 00:43:29.400 --> 00:43:31.180 Here, the transparency value is applied 730 00:43:31.180 --> 00:43:33.000 So that we only see this image 731 00:43:33.000 --> 00:43:35.520 That's how we set this up 732 00:43:35.520 --> 00:43:39.720 Now, let's close the settings window for Material 733 00:43:39.720 --> 00:43:43.880 Let's grab our new Material here 734 00:43:43.880 --> 00:43:47.266 And drag it into the Materials 735 00:43:47.266 --> 00:43:49.136 And now we see the mask 736 00:43:49.136 --> 00:43:51.660 But for this plane, the size is 737 00:43:51.660 --> 00:43:54.541 A meter by another meter 738 00:43:54.541 --> 00:43:58.500 And a mask that big isn't for a human face 739 00:43:58.500 --> 00:44:01.480 So in order to change its size to something wearable 740 00:44:01.480 --> 00:44:06.180 Let's change its scale values, width to around 0.2 741 00:44:06.180 --> 00:44:08.160 Which is around 20cm 742 00:44:08.160 --> 00:44:12.620 And length, 0.1 743 00:44:12.620 --> 00:44:14.800 So 10cm 744 00:44:15.900 --> 00:44:20.820 So here, width 20cm, length 20cm 745 00:44:20.820 --> 00:44:24.070 That's the plane size for this mask image 746 00:44:24.070 --> 00:44:27.820 And then for this, let's change it into World 747 00:44:27.820 --> 00:44:31.770 For World coordinate, where is the front? 748 00:44:31.770 --> 00:44:34.300 This red arrow here 749 00:44:34.300 --> 00:44:36.250 That's the 'front' direction of this World 750 00:44:36.250 --> 00:44:38.740 Notice how the mask is lying on the ground 751 00:44:38.740 --> 00:44:41.440 So let's change it using rotation tool 752 00:44:41.440 --> 00:44:46.380 To erect this mask to 90 degrees 753 00:44:46.380 --> 00:44:50.540 And let's turn it by 90 degrees to this side 754 00:44:50.540 --> 00:44:54.880 In order to set it up like this 755 00:44:54.880 --> 00:44:57.310 So, the face that this detects 756 00:44:57.310 --> 00:45:01.520 Its coordinates are now World coordinate 757 00:45:01.520 --> 00:45:06.640 Which will be around the center of the face detected 758 00:45:06.640 --> 00:45:11.990 But this mask isn't to be located 759 00:45:11.990 --> 00:45:13.260 At the center of the face 760 00:45:13.260 --> 00:45:16.706 Which will be around the tip of the nose 761 00:45:16.706 --> 00:45:20.060 And this needs to be worn a bit higher than that 762 00:45:20.060 --> 00:45:24.640 So in order to resettle that center 763 00:45:24.640 --> 00:45:30.600 Let's bring the plane up by 5cm or 6cm 764 00:45:30.600 --> 00:45:33.180 Let's bring it up by 6 765 00:45:33.180 --> 00:45:36.600 Here, this decimal point isn't clean enough 766 00:45:36.600 --> 00:45:39.980 So 90, 0, -90 767 00:45:39.980 --> 00:45:42.200 That will keep the rotation value we had 768 00:45:42.200 --> 00:45:46.360 Compile and save 769 00:45:47.900 --> 00:45:51.800 Again, Hunet Player Pawn Blueprint 770 00:45:51.800 --> 00:45:54.280 Back to the settings 771 00:45:54.280 --> 00:45:58.850 So to that detected face 772 00:45:58.850 --> 00:46:02.000 We worked up until using World coordinates 773 00:46:02.000 --> 00:46:06.600 And then, for that location, what we are to do is 774 00:46:06.600 --> 00:46:11.650 Spawn Actor From Class 775 00:46:11.650 --> 00:46:13.980 And let's spawn an actor 776 00:46:13.980 --> 00:46:19.940 And let's spawn BP_MaskActor 777 00:46:19.940 --> 00:46:23.600 We will be spawning a mask actor 778 00:46:23.600 --> 00:46:27.600 And then the location, we can use this 779 00:46:27.600 --> 00:46:30.360 The location of the detected face 780 00:46:30.360 --> 00:46:32.860 Here, Get All Geometry 781 00:46:32.860 --> 00:46:35.600 The one we got as Face Geometry 782 00:46:35.600 --> 00:46:39.600 The 0th one, the first detected one 783 00:46:39.600 --> 00:46:42.200 Its World coordinates are brought in 784 00:46:42.200 --> 00:46:43.980 And to that World coordinate 785 00:46:43.980 --> 00:46:48.240 We will spawn and add the mask actor 786 00:46:48.240 --> 00:46:50.740 For Collection Handling Override 787 00:46:50.740 --> 00:46:53.860 To make it spawn no matter what 788 00:46:53.860 --> 00:46:58.000 Let's set it as 'Always Spawn' 789 00:46:58.000 --> 00:47:00.580 Compile and save 790 00:47:03.780 --> 00:47:05.980 Since we are done with the setups 791 00:47:05.980 --> 00:47:09.900 Now let's package it to put it up to a test 792 00:47:09.900 --> 00:47:12.420 Last class, for project settings 793 00:47:12.420 --> 00:47:14.800 I said that for Android 794 00:47:14.800 --> 00:47:16.130 If you made a new level 795 00:47:16.130 --> 00:47:18.100 You need to add it here 796 00:47:18.100 --> 00:47:23.000 So go to this Packaging tab 797 00:47:23.000 --> 00:47:27.269 And under Advanced 798 00:47:27.269 --> 00:47:29.319 There is 'List of Maps' 799 00:47:29.319 --> 00:47:30.620 And at 'List of Maps' 800 00:47:30.620 --> 00:47:32.783 We have up until MainMap 801 00:47:32.783 --> 00:47:34.919 But the one we just made, Lobby isn't added 802 00:47:34.919 --> 00:47:37.360 So click on the plus button 803 00:47:37.360 --> 00:47:40.640 And click on this dotted area 804 00:47:40.640 --> 00:47:42.360 And you will see our LobbyMap 805 00:47:42.360 --> 00:47:47.140 So double click on LobbyMap to add 806 00:47:48.800 --> 00:47:51.380 Select LobbyMap 807 00:47:51.380 --> 00:47:54.140 And at 'Maps and Modes' 808 00:47:54.140 --> 00:47:57.600 The default map, the first one with the build 809 00:47:57.600 --> 00:47:59.600 The first map to run 810 00:47:59.600 --> 00:48:01.700 The game's default map 811 00:48:01.700 --> 00:48:08.160 Now we can change it to our LobbyMap 812 00:48:08.160 --> 00:48:11.780 Change it to LobbyMap 813 00:48:11.780 --> 00:48:14.480 Since we are now all set 814 00:48:14.480 --> 00:48:17.600 Let's work on the packaging 815 00:48:17.600 --> 00:48:20.650 At Platforms, go to Android 816 00:48:20.650 --> 00:48:23.600 Click on Package Project 817 00:48:23.600 --> 00:48:26.380 Same as what we did last time 818 00:48:26.380 --> 00:48:28.600 We mad our Package folder 819 00:48:28.600 --> 00:48:32.600 So select the folder here 820 00:48:32.600 --> 00:48:35.600 And let's start the packaging 821 00:48:38.840 --> 00:48:43.600 When packaging is done, we need to copy the file 822 00:48:43.600 --> 00:48:47.740 Go to where we have our Hunet AR Project 823 00:48:47.740 --> 00:48:49.790 At Package folder 824 00:48:49.790 --> 00:48:53.420 Go to Android_Multi folder 825 00:48:53.440 --> 00:48:55.600 And you'll see an apk file 826 00:48:55.600 --> 00:48:59.600 Ctrl+C on this apk file to copy 827 00:48:59.600 --> 00:49:02.040 Ctrl+C to copy 828 00:49:02.040 --> 00:49:05.100 And on our smartphone 829 00:49:05.100 --> 00:49:08.100 We made a folder called Unreal App 830 00:49:08.100 --> 00:49:11.080 And the file that exists here 831 00:49:11.100 --> 00:49:14.440 Let's press Del to delete 832 00:49:14.440 --> 00:49:16.940 And then Ctrl+V 833 00:49:16.940 --> 00:49:21.260 In order to copy the file we just packaged 834 00:49:23.600 --> 00:49:26.600 After copying it 835 00:49:26.600 --> 00:49:29.600 Let's go to the installed files menu 836 00:49:29.600 --> 00:49:35.460 Double click on Hunet AR apk file 837 00:49:35.460 --> 00:49:39.600 And run its package installation program 838 00:49:39.600 --> 00:49:43.600 Let's select 'install' 839 00:49:46.900 --> 00:49:48.600 When the installation is over 840 00:49:48.600 --> 00:49:52.600 Let's open it 841 00:49:52.600 --> 00:49:56.300 Press 'accept' 842 00:49:56.300 --> 00:49:59.820 And we see the detection type 843 00:49:59.820 --> 00:50:05.420 Let's go for 'Face Type' in the center 844 00:50:05.420 --> 00:50:08.820 Then this will give us the pop up for the front camera 845 00:50:08.820 --> 00:50:11.980 Let's choose 'allow only when using the app' 846 00:50:11.980 --> 00:50:13.600 And we get the front camera like so 847 00:50:13.600 --> 00:50:16.220 While it does create the mask 848 00:50:16.220 --> 00:50:18.730 Every time i move my face, Tick respawns it 849 00:50:18.730 --> 00:50:21.600 So there are too many 850 00:50:21.600 --> 00:50:24.600 Let go back to Hunet Player Pawn 851 00:50:24.600 --> 00:50:29.160 And let's not spawn every Tick 852 00:50:29.160 --> 00:50:32.980 When first spawned, these return values 853 00:50:32.980 --> 00:50:36.600 Let's make them into variables at Promote Variables 854 00:50:36.600 --> 00:50:39.250 This new variable, NewVar 855 00:50:39.250 --> 00:50:41.200 Let's rename it 856 00:50:41.200 --> 00:50:44.600 NewVar's name is 857 00:50:47.320 --> 00:50:54.120 Mask_Instance 858 00:50:54.120 --> 00:50:57.600 That's the variable name 859 00:50:57.600 --> 00:51:02.000 Then here, see how the name changed to Mask_Instance 860 00:51:02.000 --> 00:51:05.640 Let's set at this Mask_Instance variable 861 00:51:07.040 --> 00:51:11.300 So this won't spawn every time 862 00:51:11.300 --> 00:51:16.800 This time, we will get a value at Mask_Instance 863 00:51:16.800 --> 00:51:19.380 And for that, Is Valid 864 00:51:21.600 --> 00:51:25.080 We'll connect Is Valid function 865 00:51:25.080 --> 00:51:28.440 To check first whether the created mask is already 866 00:51:28.440 --> 00:51:29.980 In the variable 867 00:51:29.980 --> 00:51:34.330 True button, let's connect it 868 00:51:34.330 --> 00:51:36.560 To this Exec here 869 00:51:36.560 --> 00:51:38.550 And if Valid 870 00:51:38.550 --> 00:51:41.220 Then the mask is already spawned 871 00:51:41.220 --> 00:51:52.600 So here, we'll go for Set Actor Transform 872 00:51:52.600 --> 00:51:56.200 Set Actor Transform 873 00:51:56.200 --> 00:52:00.100 For target, we can just use Mask Instance 874 00:52:00.100 --> 00:52:03.880 Let's connect Mask Instance as the target 875 00:52:03.900 --> 00:52:06.200 Like so, let's connect the target 876 00:52:06.200 --> 00:52:08.520 From Mask Instance 877 00:52:12.020 --> 00:52:15.160 And if Invalid, we need to spawn one 878 00:52:15.160 --> 00:52:18.880 Since Invalid means that there is no value to the variable 879 00:52:18.880 --> 00:52:22.340 Let's connect it so that it can spawn 880 00:52:22.340 --> 00:52:26.300 At Spawn Actor, Mask Actor 881 00:52:26.300 --> 00:52:28.600 Compile 882 00:52:28.600 --> 00:52:31.020 I forgot to set the location 883 00:52:31.020 --> 00:52:33.370 Local transformation location value 884 00:52:33.370 --> 00:52:35.460 The facial location is the same 885 00:52:35.460 --> 00:52:38.960 So let's connect that facial location value 886 00:52:38.960 --> 00:52:41.860 Compile and save 887 00:52:41.860 --> 00:52:43.920 And let's try packaging again 888 00:52:50.440 --> 00:52:54.080 Same thing, choose Face Type 889 00:52:54.080 --> 00:52:55.890 Allow only when using the app 890 00:52:55.890 --> 00:52:58.940 So while allowing the front camera 891 00:52:58.940 --> 00:53:00.340 We raised it up by 6cm before 892 00:53:00.340 --> 00:53:02.600 And i guess 6cm is a little too high 893 00:53:02.600 --> 00:53:05.220 Anyhow, whenever I move my face 894 00:53:05.220 --> 00:53:07.320 We can see that the mask respawns 895 00:53:07.320 --> 00:53:09.600 With the new location for the face 896 00:53:09.600 --> 00:53:13.440 But the problem is, if i turn my face sideways 897 00:53:13.440 --> 00:53:16.700 It does not recognize the rotation value 898 00:53:16.700 --> 00:53:19.780 So since it is set at the center of the face 899 00:53:19.780 --> 00:53:22.340 It follows the face well 900 00:53:22.340 --> 00:53:25.480 But the rotation value, when the face 901 00:53:25.480 --> 00:53:27.820 When the face location is fixed 902 00:53:27.820 --> 00:53:30.440 When I just turn my head around 903 00:53:30.440 --> 00:53:32.880 Notice how it fails to follow promptly 904 00:53:32.880 --> 00:53:37.400 So let's get an actual location on the face 905 00:53:37.400 --> 00:53:39.700 And set this again with that point 906 00:53:40.339 --> 00:53:43.400 Detecting Particular Facial Point 907 00:53:44.660 --> 00:53:48.080 Before that, as we saw 908 00:53:48.080 --> 00:53:51.600 The position was a little too high on the face 909 00:53:51.600 --> 00:53:55.600 So let's move the mask actor plane location 910 00:53:55.600 --> 00:53:58.440 A little less than 6cm 911 00:53:58.440 --> 00:54:02.414 Let's say around 4cm 912 00:54:02.414 --> 00:54:04.594 Save 913 00:54:05.600 --> 00:54:10.450 And let's not make it the center of the face 914 00:54:10.450 --> 00:54:14.420 Let's instead position it on the tip of the nose 915 00:54:14.420 --> 00:54:18.600 So let's go back to Hunet Player Pawn settings window 916 00:54:18.600 --> 00:54:20.300 To set the location 917 00:54:20.300 --> 00:54:25.940 This time, at Geometry Class 918 00:54:25.940 --> 00:54:28.600 We can bring in the World coordinate right away 919 00:54:28.600 --> 00:54:31.980 So this center coordinate for the face 920 00:54:31.980 --> 00:54:35.660 Let's disconnect this pin 921 00:54:39.020 --> 00:54:42.240 Let's actually bring it down a bit 922 00:54:42.240 --> 00:54:45.400 And here, this first value 923 00:54:45.400 --> 00:54:47.240 Let's cast that value 924 00:54:47.240 --> 00:54:52.880 Cast to GoogleARCoreAugmentedFace 925 00:54:52.880 --> 00:54:55.820 Let's change it to this class 926 00:54:55.820 --> 00:54:57.220 A pretty long name, right? 927 00:54:57.220 --> 00:55:03.360 It's very long, so let's put it here 928 00:55:03.360 --> 00:55:07.540 Let's not connect the Exec Pin right away here 929 00:55:08.860 --> 00:55:12.720 Only cast when it is True at this branch 930 00:55:14.080 --> 00:55:17.960 Let's change the Exec Pin connection like so 931 00:55:20.000 --> 00:55:23.420 And then at GoogleARCoreAugmentedFace 932 00:55:23.420 --> 00:55:26.600 At this actual face 933 00:55:26.600 --> 00:55:33.520 Get local to world transform of region 934 00:55:33.520 --> 00:55:36.180 Region meaning a specific location 935 00:55:36.180 --> 00:55:38.600 Such as eyes, nose or the mouth 936 00:55:38.600 --> 00:55:41.020 This will bring World coordinate for those 937 00:55:41.020 --> 00:55:44.600 Get Local to World Transform of Region 938 00:55:44.600 --> 00:55:48.360 Let's add this node like so 939 00:55:48.360 --> 00:55:51.940 See, when we set a particular region 940 00:55:51.940 --> 00:55:54.480 We can go for three parts 941 00:55:54.480 --> 00:55:57.180 The Nose Tip 942 00:55:57.180 --> 00:55:58.720 Which is the tip of the nose 943 00:55:58.720 --> 00:56:01.940 And then the forehead 944 00:56:01.940 --> 00:56:04.600 The left and the right of the forehead 945 00:56:04.600 --> 00:56:07.600 And when it says Forehead, it means 946 00:56:07.600 --> 00:56:10.980 Anything higher than the brow 947 00:56:10.980 --> 00:56:12.600 That's what this calls Forehead 948 00:56:12.600 --> 00:56:15.600 Let's actually use that region 949 00:56:15.600 --> 00:56:18.160 Left and Right of Forehead 950 00:56:18.160 --> 00:56:21.380 Then it will specify area above the brow 951 00:56:21.380 --> 00:56:24.600 So for us, we can use these three 952 00:56:24.600 --> 00:56:28.880 To calculate the specific regions on the face 953 00:56:28.880 --> 00:56:31.020 As long as we know where the eyes, nose and mouth are 954 00:56:31.020 --> 00:56:33.160 We will use the tip of the nose 955 00:56:33.160 --> 00:56:38.160 As where the mask actor will be spawned 956 00:56:41.600 --> 00:56:46.600 So let's push these nodes a little further 957 00:56:46.600 --> 00:56:51.240 And let's connect it to Valid here 958 00:56:51.240 --> 00:56:52.600 Let's bring this up a little 959 00:56:52.600 --> 00:56:57.040 And let's connect it to our Valid Exec Pin 960 00:56:57.040 --> 00:56:58.600 Others remain the same 961 00:56:58.600 --> 00:57:02.140 But while this used to connect directly 962 00:57:02.140 --> 00:57:04.680 Directly connected like so 963 00:57:04.680 --> 00:57:09.000 And it began with the face center coordinate 964 00:57:09.000 --> 00:57:10.600 But this time we use Nose Tip 965 00:57:10.600 --> 00:57:13.600 So we bring in the nose tip from the face separately 966 00:57:13.600 --> 00:57:19.040 So when this location is created separately 967 00:57:19.040 --> 00:57:23.240 Or if already separated, when the location is changed 968 00:57:26.360 --> 00:57:30.540 This will connect like so 969 00:57:31.600 --> 00:57:37.200 Compile and save 970 00:57:37.200 --> 00:57:40.600 Let's try the build again like so 971 00:57:47.020 --> 00:57:49.600 This will now detect the face 972 00:57:49.600 --> 00:57:52.600 And since it uses Nose Tip location 973 00:57:52.600 --> 00:57:54.600 When we turn the face 974 00:57:54.600 --> 00:57:57.600 The image will rotate with the face 975 00:57:57.600 --> 00:57:59.600 As we see here 976 00:57:59.600 --> 00:58:01.600 So compared to before 977 00:58:01.600 --> 00:58:04.360 When we used the face center 978 00:58:04.360 --> 00:58:06.140 When we use Nose Tip 979 00:58:06.140 --> 00:58:09.140 This becomes more accurate 980 00:58:09.140 --> 00:58:10.390 So that's how 981 00:58:10.390 --> 00:58:13.600 We use face detection 982 00:58:14.880 --> 00:58:20.060 Great job everyone for powering through such a long class 983 00:58:20.060 --> 00:58:23.300 Next time, we will use the marker image and 984 00:58:23.300 --> 00:58:27.840 Implement the Image Detection part of this 985 00:58:27.840 --> 00:58:29.600 Thank you 986 00:58:29.600 --> 00:58:33.140 Let's summarize what we learned today 987 00:58:33.140 --> 00:58:36.840 Fist, we created Enumeration file 988 00:58:36.840 --> 00:58:39.600 And allowed for distinguishing Detection type 989 00:58:39.600 --> 00:58:41.940 Based on the user preference 990 00:58:41.940 --> 00:58:43.900 Using a widget that we created 991 00:58:43.900 --> 00:58:46.600 Second, we worked with AR Session Config Data 992 00:58:46.600 --> 00:58:49.600 And set the session type properties 993 00:58:49.600 --> 00:58:52.080 To allow for face detection function 994 00:58:52.080 --> 00:58:54.360 And to allow for the actual use 995 00:58:54.360 --> 00:58:57.060 Third, the facial region 996 00:58:57.060 --> 00:58:59.600 Such as Forehead or Nose Tip 997 00:58:59.600 --> 00:59:01.600 Using these particular detection regions 998 00:59:01.600 --> 00:59:03.600 We were able to display our actor 999 00:59:03.600 --> 00:59:06.600 That syncs well even when the face moves around 1000 00:59:06.600 --> 00:59:08.080 It's not only for actors 1001 00:59:08.080 --> 00:59:10.600 We can also add things like Niagara effects 1002 00:59:10.600 --> 00:59:13.000 To add various effects 1003 00:59:13.579 --> 00:59:14.247 Face Detection Data Asset Preparation In DataAssets folder, create HunetARSessionConfig_Face file for face detection 1004 00:59:14.267 --> 00:59:14.763 Open settings, set Session Type as Face Enum Class Data Creation Create Enum class file 1005 00:59:14.763 --> 00:59:15.466 Double click on EDetection Type file, +Add Click on Enumeration to add three Enum type constants 1006 00:59:15.466 --> 00:59:16.084 At BP_PlayerPawn settings, create a variable ECurrentDetection with EDetection Type as data type 1007 00:59:16.084 --> 00:59:16.693 At Event BeginPlay node, use Switch node to branch AR Session nodes to distinguish detection types 1008 00:59:16.693 --> 00:59:17.304 Data for Start AR Session node connected to Face Detection Exec Pin: set HunetARSessionConfig_Face file 1009 00:59:17.304 --> 00:59:17.944 Setting LobbyMap Select Empty Level, place PlayerStart actor at default World (0,0,0) Create a new Blueprint file at Blueprints folder 1010 00:59:17.944 --> 00:59:18.643 Parent class: GameModeBase class Set the file at GameMode Override at World Setting tab 1011 00:59:18.643 --> 00:59:19.248 Create Lobby Widget Content Drawer, create a folder called UI 1012 00:59:19.248 --> 00:59:19.777 +Add - User interface - Widget Blueprint to create a new widget 1013 00:59:19.797 --> 00:59:20.447 Parent class: UserWidget Open widget settings and add Canvas Panel at the left hierarchy panel 1014 00:59:20.447 --> 00:59:20.961 Create three Button components as child component of Canvas Panel 1015 00:59:20.961 --> 00:59:21.621 Face Detection Create AR Game Instance Create a new Blueprint file, set parent class as GameInstance 1016 00:59:21.621 --> 00:59:22.122 Open BR_ARGameInstance file settings and create a variable with EDetection type as data type 1017 00:59:22.122 --> 00:59:22.502 At Game Instance Class, set BR_ARGameInstance 1018 00:59:22.502 --> 00:59:23.097 Click on a button at Lobby Widget to implement the function Open settings and select Ground Type 1019 00:59:23.097 --> 00:59:23.587 Click on + at OnClicked event Add a node to get BP_ARGameInstance 1020 00:59:23.587 --> 00:59:23.793 At BP_ARGameInstance class, set Selected Detection Type variable to GroundDetection 1021 00:59:24.093 --> 00:59:24.560 Connect Open Level node and type MainMap to the level to move to 1022 00:59:24.560 --> 00:59:25.060 For Face Type and Image Type buttons, also set Detection Type for the designated OnClicked events 1023 00:59:25.060 --> 00:59:25.642 Adding Image and Effects Creating Mask Actor Right click on Mask texture file, choose Create Material to create a new material 1024 00:59:25.642 --> 00:59:26.122 Blend Mode: Translucent Connect A Exec Pin of Texture Sample to Opacity at M_Mask Node 1025 00:59:26.122 --> 00:59:26.682 Create a new Actor Blueprint file called BP_MaskActor Open blueprint settings and add Plane component at Components panel 1026 00:59:26.682 --> 00:59:27.273 At the right Details panel, set M_Mask file under Materials 1027 00:59:27.273 --> 00:59:27.762 Face Detection Implementation Open BP_HunetPlayerPawn settings, connect Switch node for EDetection Type at Event Tick node 1028 00:59:27.762 --> 00:59:28.195 At Face Detection Exec Pin, connect Get All AR Geometries By Class node for face detection 1029 00:59:28.195 --> 00:59:28.755 Set Geometry Class to detect as ARFace Geometry 1030 00:59:28.755 --> 00:59:29.215 -If Branch node is True, connect to use SpawnActor node to create BP_MaskActor 1031 00:59:29.215 --> 00:59:29.802 To avoid overlapping spawn, create Mask Instance variable and set Reference of spawned actor 1032 00:59:29.802 --> 00:59:31.002 Location Detection for Facial Region Getting location for facial region GoogleAR Plugin supports Left and Right Forehead and Nose Tip location values 1033 00:59:31.002 --> 00:59:31.942 Connect Cast To GoogleARCoreAugmentedFace Node to ARFace Geometry Node 1034 00:59:31.942 --> 00:59:33.289 To get coordinate for Nose Tip, set Nose Tip for Region at Get Local to World Transform Of Region