WEBVTT 1 00:00:31.000 --> 00:00:33.400 Hello, this is Younghoon Lee 2 00:00:33.400 --> 00:00:36.451 This session, we'll work on creating an Enemy 3 00:00:36.451 --> 00:00:39.001 And handling multiple spawns 4 00:00:39.001 --> 00:00:44.000 In this chapter, we'll learn how to create an enemy actor in C++ 5 00:00:44.000 --> 00:00:48.000 And how to make it move in random directions 6 00:00:48.000 --> 00:00:50.500 We'll also learn how to use 7 00:00:50.501 --> 00:00:54.801 An enemy spawner to periodically spawn enemy actors 8 00:00:55.652 --> 00:00:57.986 Creating Enemies and Setting Direction 9 00:00:59.250 --> 00:01:01.701 To make an enemy actor 10 00:01:01.701 --> 00:01:04.701 Let's make enemy class with C++ first 11 00:01:05.600 --> 00:01:09.600 Select C++ class from tools 12 00:01:09.601 --> 00:01:11.501 Here, select the actor 13 00:01:12.000 --> 00:01:13.900 Click Next 14 00:01:14.551 --> 00:01:20.101 And right here, Enemy Vector 15 00:01:25.350 --> 00:01:28.550 We will create enemy spawn with direction upon creation 16 00:01:28.550 --> 00:01:31.300 It may go forward 17 00:01:31.301 --> 00:01:33.301 Or for like 30% chance 18 00:01:33.851 --> 00:01:37.750 Making it head to the player right away 19 00:01:37.751 --> 00:01:39.701 That's the kind of the enemy we want 20 00:01:39.701 --> 00:01:43.000 Let's start by creating an enemy that moves forward 21 00:01:45.700 --> 00:01:49.000 If you do this, the class will be created in C++ 22 00:01:49.000 --> 00:01:51.000 Called Enemy Actor 23 00:02:03.750 --> 00:02:07.200 Then we need to handle the appearance 24 00:02:07.201 --> 00:02:09.501 And collision object for the Enemy Actor 25 00:02:10.000 --> 00:02:13.600 Go down to the bottom 26 00:02:13.601 --> 00:02:15.951 Start with public 27 00:02:16.500 --> 00:02:19.000 Then, UPROPERTY 28 00:02:26.000 --> 00:02:29.000 EditAnywhere for now 29 00:02:29.450 --> 00:02:31.950 After this 30 00:02:31.951 --> 00:02:37.801 We need the collision object and the appearance 31 00:02:38.200 --> 00:02:41.700 So let's do a forward declaration 32 00:02:41.701 --> 00:02:43.301 And then collision object 33 00:02:43.301 --> 00:02:48.000 Write UBoxComponent 34 00:02:57.000 --> 00:03:01.500 And then write code for appearance as well 35 00:03:01.801 --> 00:03:05.451 With Static Mesh Component 36 00:03:15.300 --> 00:03:17.100 Static Mesh Component 37 00:03:17.400 --> 00:03:20.000 And then, MeshComp 38 00:03:27.000 --> 00:03:30.450 What we want to do is this 39 00:03:30.450 --> 00:03:36.100 Decide the direction to move to when spawned 40 00:03:36.451 --> 00:03:42.601 While it lives, it will want to move to certain direction 41 00:03:43.000 --> 00:03:45.000 This is What we want 42 00:03:45.600 --> 00:03:49.400 For spawning 43 00:03:49.851 --> 00:03:52.051 We have a function called BeginPlay 44 00:03:52.051 --> 00:03:54.000 And then there is Tick 45 00:03:54.000 --> 00:03:55.800 With these two functions 46 00:03:55.800 --> 00:03:59.051 Enemy spawns at Begin Play 47 00:03:59.051 --> 00:04:02.000 Tick will handle while lives part 48 00:04:02.800 --> 00:04:08.000 So, we are using the same concept with different functions 49 00:04:08.000 --> 00:04:11.000 We now need an attribute of directrion 50 00:04:11.700 --> 00:04:15.000 We now need an attribute of directrion 51 00:04:15.000 --> 00:04:18.100 This one starts with UPROPERTY as well 52 00:04:18.100 --> 00:04:19.600 We don't have to do this 53 00:04:19.601 --> 00:04:21.001 But You may want to see it 54 00:04:21.001 --> 00:04:28.000 Then let me put EditAnywhere 55 00:04:28.450 --> 00:04:31.400 FVector 56 00:04:31.400 --> 00:04:34.000 And then direction 57 00:04:37.000 --> 00:04:39.100 We don't have to write this 58 00:04:39.101 --> 00:04:40.101 But if we have it 59 00:04:40.102 --> 00:04:43.002 We will be able to see it in blueprint 60 00:04:44.000 --> 00:04:47.000 That's it 61 00:04:47.550 --> 00:04:51.000 Let's go to C++ source file 62 00:04:51.500 --> 00:04:55.600 And now here, we decide the direction when spawned 63 00:04:58.000 --> 00:05:04.000 While it lives, it will want to keep moving 64 00:05:04.600 --> 00:05:07.000 That's how I want to implement this 65 00:05:09.100 --> 00:05:12.000 We need to work on appearance and collision object as well 66 00:05:12.350 --> 00:05:18.900 I want to create collision object component 67 00:05:18.901 --> 00:05:22.601 And place it in the root 68 00:05:23.000 --> 00:05:28.751 And create appearance component 69 00:05:28.751 --> 00:05:31.751 Attach it to the root 70 00:05:32.000 --> 00:05:35.000 This will do the job 71 00:05:35.000 --> 00:05:38.000 Let's make it happen one by one 72 00:05:40.100 --> 00:05:43.050 First, let's work on collision object component 73 00:05:43.050 --> 00:05:46.700 BoxComp 74 00:05:48.200 --> 00:05:52.650 CreateDefaultSuboject 75 00:05:52.650 --> 00:05:54.250 Do you remember now? 76 00:05:54.250 --> 00:05:56.000 Write it like this 77 00:05:57.000 --> 00:05:59.000 This one is UBoxComponent 78 00:06:00.200 --> 00:06:01.500 Write the name here 79 00:06:01.501 --> 00:06:02.801 TEXT 80 00:06:04.250 --> 00:06:07.850 And put BoxComp here as well 81 00:06:08.350 --> 00:06:10.200 I've mentioned this before 82 00:06:10.201 --> 00:06:11.851 The name that goes in here 83 00:06:11.900 --> 00:06:14.450 Feel free to write however you are comfortable 84 00:06:14.450 --> 00:06:17.500 However, there can't be two of the same name 85 00:06:17.950 --> 00:06:20.000 Just keep that in mind 86 00:06:21.050 --> 00:06:26.300 I will add BoxComp to the root component in SetRootComponent 87 00:06:31.100 --> 00:06:32.350 The reason for the error is 88 00:06:32.351 --> 00:06:34.000 Because the header wasn't included 89 00:06:34.000 --> 00:06:36.350 Therefore, let's add the header file 90 00:06:36.350 --> 00:06:41.250 So, I'll mention this again now 91 00:06:41.250 --> 00:06:43.000 I am using Visual Assist 92 00:06:43.000 --> 00:06:44.550 That's why it appears this way 93 00:06:44.550 --> 00:06:46.450 You all can type it out yourselves 94 00:06:46.450 --> 00:06:49.000 So we have these two 95 00:06:49.850 --> 00:06:54.950 You can type like this, Component and BoxComponent 96 00:06:55.700 --> 00:06:59.000 Let's make the appearance 97 00:06:59.000 --> 00:07:03.100 Make MeshComp first 98 00:07:04.000 --> 00:07:09.000 Write CreateDefaultSubobject 99 00:07:17.750 --> 00:07:22.000 And UStaticMeshComponent here 100 00:07:22.300 --> 00:07:24.700 Write it like this 101 00:07:24.700 --> 00:07:27.500 And then it must be attached to Root 102 00:07:27.500 --> 00:07:31.000 MeshComponent will be 103 00:07:31.000 --> 00:07:35.000 Attached to Root 104 00:07:35.000 --> 00:07:37.000 Through function called SetupAttachment 105 00:07:37.000 --> 00:07:40.000 RootComponent 106 00:07:40.000 --> 00:07:45.000 Or you can write BoxComp 107 00:07:46.350 --> 00:07:50.000 Place them like this 108 00:07:54.000 --> 00:07:56.000 Go to the bottom 109 00:07:56.000 --> 00:07:58.700 Now let's make it move 110 00:07:58.700 --> 00:08:02.000 We will need direction in order to move 111 00:08:02.000 --> 00:08:04.450 Write Direction 112 00:08:04.450 --> 00:08:06.400 I will call it foward 113 00:08:06.400 --> 00:08:15.200 Direction is GetActor and Forward Verctor 114 00:08:15.200 --> 00:08:18.000 Write it like this 115 00:08:18.950 --> 00:08:21.150 If you are going to move things 116 00:08:21.150 --> 00:08:23.400 You need to set the direction, size and speed 117 00:08:23.400 --> 00:08:25.600 We haven't made the speed 118 00:08:25.600 --> 00:08:29.000 Let's go this way and create Speed as well 119 00:08:29.850 --> 00:08:33.550 Write float Speed 120 00:08:33.850 --> 00:08:37.050 Since it's an Enemy, let's set it to 500 121 00:08:37.050 --> 00:08:42.000 Likewise, we'll give it the UPROPERTY attribute 122 00:08:42.650 --> 00:08:44.550 It's okay not to give this one 123 00:08:44.550 --> 00:08:46.000 In this structure 124 00:08:46.000 --> 00:08:47.500 However, I wrote this down 125 00:08:47.501 --> 00:08:50.651 Was for me to check 126 00:08:50.651 --> 00:08:53.800 This could be modified by the director 127 00:08:53.800 --> 00:08:58.400 Therefore, that's why I wrote it 128 00:08:58.400 --> 00:09:00.550 It means that it can now be seen from the outside 129 00:09:00.550 --> 00:09:05.000 That's that and come back 130 00:09:05.300 --> 00:09:07.350 Now let's move 131 00:09:07.350 --> 00:09:09.650 We've already made movement formula multiple times now 132 00:09:09.650 --> 00:09:14.600 P equals P0 plus Vt 133 00:09:15.250 --> 00:09:18.050 P0 to FVector 134 00:09:18.050 --> 00:09:25.000 P0 is current location, GetActorLocation 135 00:09:25.000 --> 00:09:28.000 Like so 136 00:09:28.300 --> 00:09:32.000 And then make Velocity 137 00:09:32.000 --> 00:09:36.000 Direction and Speed are already prepared here 138 00:09:36.000 --> 00:09:40.000 So, up to Vt, you just need to multiply these three together 139 00:09:40.000 --> 00:09:45.000 Now, I will use SetActorLocation here 140 00:09:45.500 --> 00:09:53.200 Like this P0 plus Velocity 141 00:09:53.200 --> 00:09:54.350 We don't have Velocity now 142 00:09:54.350 --> 00:10:01.000 Direction times Speed 143 00:10:01.000 --> 00:10:03.000 That will give us Velocity 144 00:10:03.500 --> 00:10:05.000 I need to capitalize it 145 00:10:05.000 --> 00:10:08.450 It's my habit to use small letter 146 00:10:08.450 --> 00:10:12.000 Let's capitalize it 147 00:10:12.550 --> 00:10:14.000 You can use the Rename function 148 00:10:14.000 --> 00:10:17.650 You can change it all at once 149 00:10:21.000 --> 00:10:26.600 And we need to multiply this by delta time 150 00:10:28.000 --> 00:10:31.000 I'll set it like this 151 00:10:31.000 --> 00:10:35.200 I'll turn this off for now 152 00:10:37.000 --> 00:10:39.000 Now it will make it go forward 153 00:10:39.000 --> 00:10:42.000 Save all for now 154 00:10:42.000 --> 00:10:44.000 The name here also changed 155 00:10:44.000 --> 00:10:45.550 Save all 156 00:10:45.551 --> 00:10:52.101 Let's compile it 157 00:10:54.951 --> 00:10:57.750 Wait till compiling finishes 158 00:10:58.750 --> 00:11:01.300 Now let's make the enemy 159 00:11:01.300 --> 00:11:04.000 For the Enemy actor 160 00:11:04.000 --> 00:11:07.000 Go find C++ header 161 00:11:07.500 --> 00:11:09.700 Make the Enemy Actor into blueprint 162 00:11:09.701 --> 00:11:11.101 And place it here 163 00:11:11.501 --> 00:11:14.000 Create Blueprint Class 164 00:11:14.450 --> 00:11:21.000 Give the blueprint folder, suffix BP 165 00:11:21.200 --> 00:11:24.200 Now I've made blueprint class 166 00:11:24.200 --> 00:11:30.650 Then, we will put the same cube in the mesh 167 00:11:33.000 --> 00:11:35.850 Let's repeat the same process 168 00:11:35.850 --> 00:11:43.500 Here, find Basic Shape Material 169 00:11:47.000 --> 00:11:49.000 Like so 170 00:11:49.300 --> 00:11:50.800 Let's see if it moves forward 171 00:11:50.800 --> 00:11:52.450 What's the value of Speed 172 00:11:52.450 --> 00:11:54.400 The Enemy actor is set to 500 173 00:11:54.400 --> 00:11:55.900 You can see the direction here like this 174 00:11:55.900 --> 00:11:58.000 That's how we check this 175 00:11:58.000 --> 00:12:01.600 It might be hard to tell like this 176 00:12:03.300 --> 00:12:05.350 But anyway, this is how we bring out the Enemy 177 00:12:05.350 --> 00:12:07.000 Let's place it in the center 178 00:12:07.000 --> 00:12:10.000 179 00:12:10.300 --> 00:12:12.850 Since the Enemy moves forward 180 00:12:12.851 --> 00:12:14.001 It will move into the center 181 00:12:14.001 --> 00:12:17.000 So now, I'm going to rotate it a bit 182 00:12:17.000 --> 00:12:25.800 Rotate the Enemy like this 183 00:12:30.800 --> 00:12:32.750 And make it face downward 184 00:12:32.750 --> 00:12:35.950 It looks like the top is facing inward on the screen 185 00:12:35.950 --> 00:12:37.000 Make it face towards us 186 00:12:37.000 --> 00:12:39.850 It's normal to make it face towards us 187 00:12:39.850 --> 00:12:43.650 Because it's correct for the right side to move this way 188 00:12:44.400 --> 00:12:52.000 This is how it should be 189 00:12:52.650 --> 00:12:57.000 So I will rotate it like this 190 00:12:57.500 --> 00:13:00.600 Just like this 191 00:13:02.550 --> 00:13:04.400 Set the location by 180, minus 90 and 0 192 00:13:04.401 --> 00:13:06.301 I think we can handle it like this 193 00:13:08.151 --> 00:13:11.000 So, after doing it like this and moving it slightly aside 194 00:13:11.000 --> 00:13:14.400 you can see it going straight ahead when you run it 195 00:13:16.100 --> 00:13:18.550 So that was how to mak an enemy 196 00:13:18.550 --> 00:13:22.000 Let's make the enemy move randomly then 197 00:13:22.000 --> 00:13:23.700 Find the Player 198 00:13:23.701 --> 00:13:27.451 Let's create it so that it moves in the direction of play 199 00:13:30.150 --> 00:13:33.000 Move to the Enemy 200 00:13:33.000 --> 00:13:37.000 You can do this task in BeginPlay 201 00:13:37.500 --> 00:13:40.000 We will decide the direction 202 00:13:40.000 --> 00:13:41.400 Like this 203 00:13:41.400 --> 00:13:44.000 We will make it random 204 00:13:44.000 --> 00:13:46.800 With 30% chance 205 00:13:47.851 --> 00:13:50.612 Toward the player 206 00:13:53.000 --> 00:13:55.450 And remaining percentage of chance 207 00:13:56.101 --> 00:13:59.701 To bee moving forward 208 00:14:01.000 --> 00:14:04.000 I want to handle it like this 209 00:14:04.000 --> 00:14:08.550 What we previously worked on will be the forward direction 210 00:14:08.550 --> 00:14:11.400 Then we need to create a 30% probability 211 00:14:11.400 --> 00:14:14.250 When we implemented this in the blueprint 212 00:14:14.250 --> 00:14:17.350 We used randomness 213 00:14:17.351 --> 00:14:18.951 To create the percentage 214 00:14:19.000 --> 00:14:23.150 So let's work on it the same way we did 215 00:14:28.200 --> 00:14:34.000 If you look there is FMath 216 00:14:34.350 --> 00:14:36.800 This one also start with F 217 00:14:36.800 --> 00:14:39.850 The structure called FMath 218 00:14:39.850 --> 00:14:42.800 Although it's technically a structure, we learned it as a class 219 00:14:42.800 --> 00:14:46.450 There's not much difference between a structure and a class 220 00:14:46.450 --> 00:14:49.600 Basically, they have the same structure 221 00:14:49.600 --> 00:14:53.300 It's just that a structure is public by default 222 00:14:53.300 --> 00:14:55.400 While a class is private by default 223 00:14:55.400 --> 00:14:57.750 That's the main difference between them 224 00:14:58.000 --> 00:15:00.950 If you look at FMath 225 00:15:00.951 --> 00:15:06.251 You'll find something 226 00:15:06.251 --> 00:15:09.000 Called RandRange 227 00:15:09.500 --> 00:15:12.000 You can use this function 228 00:15:12.000 --> 00:15:15.250 If you want to see this again 229 00:15:15.250 --> 00:15:19.000 Place your mouse cursor over it like this 230 00:15:19.000 --> 00:15:23.000 Then press Shift and Ctrl simultaneously, and then press the spacebar 231 00:15:23.000 --> 00:15:25.400 This will allow you to view it again 232 00:15:25.400 --> 00:15:28.400 I see there are four overloads now 233 00:15:28.400 --> 00:15:30.850 One of them is for doubles 234 00:15:30.850 --> 00:15:33.000 Then there's one for floats and various other types 235 00:15:33.000 --> 00:15:37.300 There's Int32 236 00:15:37.300 --> 00:15:40.450 In Unreal Engine we use Int32 237 00:15:41.050 --> 00:15:43.450 By specifying the numbers 64 and 36 238 00:15:43.450 --> 00:15:47.900 You can consider this as defining the size 239 00:15:47.950 --> 00:15:50.200 This is included here as well 240 00:15:50.200 --> 00:15:52.000 It includes both the min and max values 241 00:15:52.000 --> 00:15:54.750 So, if you want to make it 100% 242 00:15:54.751 --> 00:15:59.701 you would use a range from 0 to 99, which would give you 100 count 243 00:15:59.701 --> 00:16:01.500 Or you could use a range from 0 to 9 244 00:16:01.500 --> 00:16:05.000 Then, if you have 3 out of 10, that would be 30% 245 00:16:05.000 --> 00:16:08.350 Let's write it like this 246 00:16:08.350 --> 00:16:11.000 Let's say 99 247 00:16:11.000 --> 00:16:16.000 By doing this, it will return a random number 248 00:16:16.400 --> 00:16:19.450 within the range from 0 to 99 249 00:16:19.450 --> 00:16:22.450 It could be 0, or it could be 99 250 00:16:22.450 --> 00:16:24.850 And it could also be any value in between 251 00:16:24.850 --> 00:16:27.000 So let's go ahead and take this 252 00:16:27.000 --> 00:16:30.000 I'll receive it as an Int32 253 00:16:31.001 --> 00:16:34.150 I will say randValue 254 00:16:36.500 --> 00:16:39.450 I have received a random value 255 00:16:39.800 --> 00:16:42.250 If this random value is smaller than 30 256 00:16:42.250 --> 00:16:44.000 It becomes 30% 257 00:16:44.000 --> 00:16:47.000 Since it is30 out of 100 right? 258 00:16:47.000 --> 00:16:52.600 So, if randValue is less than 30 259 00:16:52.600 --> 00:16:55.000 This would represent 30% 260 00:16:55.000 --> 00:16:59.800 And if it's else, it covers the remaining probability 261 00:17:04.000 --> 00:17:06.600 Like this 262 00:17:06.600 --> 00:17:10.200 The ActorForwardVector and similar vectors 263 00:17:10.200 --> 00:17:12.100 Have a magnitude of 1 264 00:17:12.100 --> 00:17:15.000 The Length is 1 265 00:17:15.450 --> 00:17:18.000 So, there's no need to normalize it separately 266 00:17:18.500 --> 00:17:21.700 So, what we have to do here is 267 00:17:22.000 --> 00:17:25.200 We need to find the player and since it's enemy 268 00:17:25.250 --> 00:17:27.000 We find the destination 269 00:17:27.000 --> 00:17:30.000 Want to find the destination 270 00:17:30.000 --> 00:17:36.000 And them, want to find the direction of the destination 271 00:17:36.650 --> 00:17:40.000 And then Normalize 272 00:17:40.000 --> 00:17:43.651 I want to normalize the vector 273 00:17:44.000 --> 00:17:48.000 So, we need to complete these three tasks 274 00:17:48.650 --> 00:17:51.000 So, when wanting to locate the destination 275 00:17:51.000 --> 00:17:55.000 Do you remember? Let's take a look 276 00:17:55.000 --> 00:17:58.000 If we briefly look at the enemy 277 00:17:58.550 --> 00:18:00.750 When trying to find the protagonist 278 00:18:00.751 --> 00:18:01.951 There are two things we can do 279 00:18:02.000 --> 00:18:03.000 Broadly speaking 280 00:18:03.000 --> 00:18:09.000 One option was a node called GetPlayerPawn 281 00:18:09.400 --> 00:18:11.050 You can use this or 282 00:18:11.051 --> 00:18:20.351 Or, we have GetActorOfClass 283 00:18:20.351 --> 00:18:22.700 Additionally, there's also AllActorsOfClass 284 00:18:22.700 --> 00:18:24.450 You can find all of them if needed 285 00:18:24.451 --> 00:18:25.851 Or you can find only one 286 00:18:26.000 --> 00:18:30.450 This is because the protagonist exists only once in this level 287 00:18:30.450 --> 00:18:32.100 So, we can use this method to find the actor if there's only one in the level 288 00:18:32.100 --> 00:18:35.000 However, if there are multiple actors in the level 289 00:18:35.400 --> 00:18:37.050 That we want to find 290 00:18:37.051 --> 00:18:39.701 Then this method won't work for finding just one 291 00:18:39.701 --> 00:18:42.000 In that case, you won’t know what will be returned 292 00:18:42.000 --> 00:18:44.300 It might not be what we want 293 00:18:44.300 --> 00:18:47.600 So, you need to distinguish between these options and use them appropriately 294 00:18:47.600 --> 00:18:51.000 Right now, we can either do this or try that 295 00:18:51.000 --> 00:18:53.900 Let's go ahead and try both of these 296 00:18:53.900 --> 00:18:55.350 First, let's try this one 297 00:18:55.350 --> 00:18:56.600 You might find 298 00:18:56.601 --> 00:18:59.101 This quite challenging at first 299 00:18:59.150 --> 00:19:01.850 One useful hint is 300 00:19:01.851 --> 00:19:03.501 To start by implementing it in Blueprint 301 00:19:03.501 --> 00:19:06.000 And then move it to C++; this can make things easier 302 00:19:06.000 --> 00:19:08.000 You can double click this 303 00:19:08.000 --> 00:19:10.000 Then, you will see a symbol like this 304 00:19:10.000 --> 00:19:12.350 This will also appear if you double click it 305 00:19:12.350 --> 00:19:15.800 There are some things that appear like this, and some that do not 306 00:19:15.800 --> 00:19:18.250 When the symbol appears like this, it makes the task easier 307 00:19:18.250 --> 00:19:22.350 Functions like this exist in UGameplayStatics 308 00:19:22.350 --> 00:19:24.800 If we use this function 309 00:19:24.800 --> 00:19:29.000 We can apply the same functionality in C++ 310 00:19:30.050 --> 00:19:32.450 Let's go through each one of these 311 00:19:32.450 --> 00:19:38.000 Let's start with GetPlayerPawn then 312 00:19:39.300 --> 00:19:42.700 The destination 313 00:19:45.650 --> 00:19:46.850 Would be the protagonist 314 00:19:46.850 --> 00:19:50.000 Since this is a function from UGameplayStatics 315 00:19:50.000 --> 00:19:55.000 We'll need to include the corresponding header, of course 316 00:19:55.350 --> 00:20:00.000 Let's search for this 317 00:20:00.000 --> 00:20:02.900 If you search for this, you'll find that the header is like this 318 00:20:02.900 --> 00:20:06.700 Kismet's GameplayStatics 319 00:20:06.700 --> 00:20:10.750 Now, please add this here as shown 320 00:20:12.000 --> 00:20:14.950 This is the simplest way to find it 321 00:20:15.800 --> 00:20:18.000 Once you get used to it and memorize it 322 00:20:18.001 --> 00:20:19.550 You can type it out directly 323 00:20:19.550 --> 00:20:22.500 Also, using tools or extensions 324 00:20:23.000 --> 00:20:26.600 Like the ones I use can be very helpful 325 00:20:26.900 --> 00:20:33.000 You can use the Visual Assistant 326 00:20:33.000 --> 00:20:34.501 By pressing Shift Alt Q. 327 00:20:34.501 --> 00:20:37.550 If you look in the Extensions Manager 328 00:20:37.551 --> 00:20:38.701 You will see two options like this 329 00:20:38.701 --> 00:20:40.550 There’s also something called ReSharper 330 00:20:40.550 --> 00:20:44.000 And using this program can make things more convenient 331 00:20:44.150 --> 00:20:48.000 You don't necessarily need to manually add it here 332 00:20:48.000 --> 00:20:51.000 As it is automatically included 333 00:20:51.000 --> 00:20:54.450 You can choose to do so if you prefer 334 00:20:55.000 --> 00:20:57.000 I'll go ahead and do it this way 335 00:20:57.000 --> 00:20:59.550 I'll start by basing it on what we don't use 336 00:20:59.550 --> 00:21:01.850 Like so 337 00:21:03.000 --> 00:21:04.950 Then, it will be ready to use 338 00:21:04.950 --> 00:21:08.000 The function, GetPlayerPawn 339 00:21:08.000 --> 00:21:10.000 if you open the parentheses 340 00:21:10.000 --> 00:21:11.550 Takes two parameters here 341 00:21:11.550 --> 00:21:14.000 The function takes WorldContext 342 00:21:14.000 --> 00:21:16.800 And Index as parameters 343 00:21:17.300 --> 00:21:20.000 If you're developing in standalone mode 344 00:21:20.000 --> 00:21:26.500 For a local play app rather than a networked one 345 00:21:26.500 --> 00:21:29.000 You can just use 0 for the index 346 00:21:29.000 --> 00:21:32.000 The local player is player 0 347 00:21:32.000 --> 00:21:35.000 So, like this 348 00:21:35.550 --> 00:21:38.000 Use GetWorld 349 00:21:38.800 --> 00:21:41.600 And provide 0 like this, you can retrieve it 350 00:21:41.600 --> 00:21:45.000 As you can see, the return type is APawn 351 00:21:45.950 --> 00:21:48.400 It returns a pointer to an APawn 352 00:21:48.400 --> 00:21:52.000 So, as you can see, we have found the player pawn 353 00:21:52.000 --> 00:21:56.000 Additionally, there is APlayerPawn and also characters 354 00:21:56.700 --> 00:22:00.000 Do you remember 355 00:22:00.500 --> 00:22:01.650 We talked about this before? 356 00:22:01.651 --> 00:22:03.451 We have an actor 357 00:22:06.600 --> 00:22:08.900 And there are also inherited pawns 358 00:22:09.600 --> 00:22:12.000 And there are also characters that inherit from it 359 00:22:14.600 --> 00:22:16.400 It's set up like this 360 00:22:16.400 --> 00:22:18.350 Fundamentally, both of these 361 00:22:18.351 --> 00:22:20.101 We can manipulate them 362 00:22:20.550 --> 00:22:25.350 They can receive input 363 00:22:25.350 --> 00:22:27.500 So, there are two types 364 00:22:27.500 --> 00:22:29.800 Depending on whether we set the protagonist 365 00:22:29.801 --> 00:22:31.601 As a player or as a pawn 366 00:22:31.601 --> 00:22:34.000 You should differentiate and use these accordingly 367 00:22:34.000 --> 00:22:37.000 Since it's set as a pawn, I'll use it this way for now 368 00:22:37.000 --> 00:22:39.500 So, we need to get this 369 00:22:39.500 --> 00:22:46.200 You can write it as APawn times Target 370 00:22:47.100 --> 00:22:53.000 However, even though it's a Pawn, you can also receive it as an AActor 371 00:22:53.000 --> 00:22:58.800 Casting is possible due to C++'s 372 00:22:58.801 --> 00:23:00.901 basic inheritance structure 373 00:23:01.000 --> 00:23:07.550 Since the casting is done as parent type, it's an example of upcasting 374 00:23:07.550 --> 00:23:10.500 It's about changing the size of the child to fit the parent type 375 00:23:10.500 --> 00:23:12.000 And we call it upcasting 376 00:23:12.000 --> 00:23:15.000 So, casting like this is possible 377 00:23:15.850 --> 00:23:20.400 Then, after finding the destination, you can calculate the direction 378 00:23:20.400 --> 00:23:22.750 For the direction 379 00:23:22.750 --> 00:23:33.500 Target minus me should do it 380 00:23:34.200 --> 00:23:37.200 As I mentioned, subtracting one vector from another 381 00:23:37.200 --> 00:23:41.000 It gives you the direction that results 382 00:23:41.000 --> 00:23:44.000 To determine the direction to the target 383 00:23:44.000 --> 00:23:48.000 You need to subtract your vector from the destination vector 384 00:23:48.000 --> 00:23:52.000 Therefore, subtract your location from the destination location 385 00:23:52.000 --> 00:24:04.000 So, Target, then GetActorLocation and subtract it 386 00:24:04.550 --> 00:24:06.350 Me is actually this 387 00:24:06.350 --> 00:24:11.000 If you align it with the line of this, you can write it like this 388 00:24:11.000 --> 00:24:13.000 You can speed this process 389 00:24:13.000 --> 00:24:17.750 GetActorLocation 390 00:24:17.751 --> 00:24:19.301 This should do the job 391 00:24:19.301 --> 00:24:24.700 Now, you can put this into the Direction 392 00:24:27.000 --> 00:24:28.750 But when you put it in like this 393 00:24:28.751 --> 00:24:31.451 It can be very far 394 00:24:31.451 --> 00:24:35.700 It becomes a bit ambiguous if it ends up being farther than 1m 395 00:24:35.700 --> 00:24:38.250 If you only know the direction 396 00:24:38.251 --> 00:24:40.351 you can make the size 1 397 00:24:41.350 --> 00:24:44.350 When you multiply 1 by any number, 1 disappears 398 00:24:44.350 --> 00:24:47.000 1 multiplied by 0.1 is 0.1 399 00:24:47.000 --> 00:24:49.900 Similarly, that's why we make this length 1 400 00:24:49.901 --> 00:24:50.951 By normalizing 401 00:24:51.000 --> 00:24:53.450 You make the size 1 402 00:24:53.451 --> 00:24:55.951 So that it can be used only for direction 403 00:24:56.100 --> 00:24:59.450 That's the reason for normalizing 404 00:24:59.450 --> 00:25:03.000 It's to make the vector meaningful 405 00:25:04.700 --> 00:25:08.300 As a direction 406 00:25:08.301 --> 00:25:11.701 By setting its magnitude to 1 407 00:25:11.701 --> 00:25:14.800 This is how you should understand it 408 00:25:14.800 --> 00:25:20.300 Now, I'll normalize the direction 409 00:25:25.300 --> 00:25:28.450 So, by doing this, it will be implemented 410 00:25:28.450 --> 00:25:29.950 This is the first method 411 00:25:29.951 --> 00:25:33.151 The method of using GetPlayerPawn 412 00:25:34.650 --> 00:25:37.750 Before trying the second method 413 00:25:37.751 --> 00:25:40.151 Let's demonstrate it first 414 00:25:40.151 --> 00:25:42.700 So with that, compile it 415 00:25:42.701 --> 00:25:43.951 And then run it 416 00:25:44.000 --> 00:25:45.050 Save all 417 00:25:45.051 --> 00:25:47.601 Save and then compile all together 418 00:25:48.400 --> 00:25:50.500 Like so 419 00:25:53.200 --> 00:25:56.000 The compile I mentioned is not this compile 420 00:25:56.000 --> 00:26:00.000 I meant the blueprint compile 421 00:26:00.000 --> 00:26:04.050 Compiling doesn't work 422 00:26:07.000 --> 00:26:10.150 Okay do this and run it 423 00:26:10.151 --> 00:26:12.451 You can see it move 424 00:26:14.000 --> 00:26:17.850 You can see it working well 425 00:26:21.000 --> 00:26:25.000 Now, this time, as you saw earlier 426 00:26:25.000 --> 00:26:26.450 I tried it with this one 427 00:26:26.451 --> 00:26:28.301 But now I'll try it with this one 428 00:26:28.301 --> 00:26:30.400 If you double click this node 429 00:26:30.401 --> 00:26:32.401 You'll see the symbol appears just like before 430 00:26:32.401 --> 00:26:37.700 Now, I'll copy this exactly as it is 431 00:26:37.700 --> 00:26:42.000 Now, I'll come back here and write it like this 432 00:26:42.600 --> 00:26:43.851 If you open the bracket 433 00:26:43.851 --> 00:26:46.401 Here, we also include the WorldContextObject 434 00:26:46.401 --> 00:26:49.900 And this time we use an Actor class 435 00:26:51.000 --> 00:26:53.450 Let's get to work 436 00:26:53.451 --> 00:26:56.151 For now, I'll comment this out 437 00:26:56.151 --> 00:27:00.100 Now, if you look here, to add a comment 438 00:27:00.100 --> 00:27:01.200 There are things like these 439 00:27:01.201 --> 00:27:04.301 We have shortcut like Ctrl+K, C, Ctrl+K, U 440 00:27:04.301 --> 00:27:07.100 Using this, you can easily add comments 441 00:27:07.200 --> 00:27:10.300 Select the block, then press Ctrl 442 00:27:10.301 --> 00:27:12.551 And, in sequence, K and C 443 00:27:12.551 --> 00:27:15.850 To uncomment, press 444 00:27:15.851 --> 00:27:17.651 Ctrl and, in sequence, K and U 445 00:27:17.651 --> 00:27:23.500 First, comment it out using Ctrl+K, C 446 00:27:23.500 --> 00:27:29.000 Now, I'll implement it using GetActorOfClass 447 00:27:29.000 --> 00:27:32.950 Similarly here, you need to put in World, so use GetWorld 448 00:27:32.950 --> 00:27:34.550 If you need to provide variable value for 449 00:27:34.551 --> 00:27:37.951 A parameter named World 450 00:27:37.951 --> 00:27:40.400 You should always use GetWorld 451 00:27:40.400 --> 00:27:41.950 Secondly 452 00:27:41.951 --> 00:27:45.551 This is where you need to put an Actor class 453 00:27:45.551 --> 00:27:48.351 This is a UClass, right? 454 00:27:48.351 --> 00:27:49.701 Do you remember that last time 455 00:27:50.000 --> 00:27:52.550 We used TSubclassOf 456 00:27:52.551 --> 00:27:55.651 Instead of a UClass pointer? 457 00:27:55.651 --> 00:27:59.600 Similarly, you can think of TSubclassOf 458 00:27:59.601 --> 00:28:01.901 As a UClass 459 00:28:02.701 --> 00:28:06.450 So you just need to put the UClass you want to find here 460 00:28:06.450 --> 00:28:10.600 So, what we're looking for is the main character 461 00:28:10.600 --> 00:28:15.000 Yes, the main character is set as PlayerPawn 462 00:28:15.000 --> 00:28:20.650 Then, write APlayerPawn here 463 00:28:28.000 --> 00:28:31.600 Yes, like this, You should write it this way 464 00:28:31.600 --> 00:28:35.600 To use this, you'll also need to add this 465 00:28:37.400 --> 00:28:39.400 In here 466 00:28:41.000 --> 00:28:44.350 Let's include it, # include 467 00:28:46.050 --> 00:28:51.850 Please add the PlayerPawn header like this 468 00:28:53.000 --> 00:28:56.000 Then, when you come back, you'll be able to use it 469 00:28:56.000 --> 00:29:01.000 After doing this, you'll see there's something called StaticClass here 470 00:29:03.500 --> 00:29:05.200 This is the UClass 471 00:29:05.201 --> 00:29:07.401 As you can see, it returns a UClass 472 00:29:08.000 --> 00:29:13.000 Do you remember what I mentioned last time? 473 00:29:13.000 --> 00:29:16.400 When you create an actor with this header tool 474 00:29:16.401 --> 00:29:19.001 It creates two things 475 00:29:20.150 --> 00:29:23.150 A UClass and a UObject 476 00:29:23.150 --> 00:29:26.000 This way, you create a UClass instance and CDO 477 00:29:26.000 --> 00:29:31.000 And this instance is what you put here 478 00:29:31.000 --> 00:29:32.750 By doing this, you can find it like this 479 00:29:32.751 --> 00:29:34.851 It returns as an Actor 480 00:29:34.851 --> 00:29:37.250 So, actually, you can just apply the same content 481 00:29:37.251 --> 00:29:39.701 You wrote here to the rest 482 00:29:39.701 --> 00:29:41.000 Like so 483 00:29:43.400 --> 00:29:45.550 We wrote it like this before 484 00:29:45.551 --> 00:29:50.900 You need to write this part here like this 485 00:29:50.900 --> 00:29:52.700 The semicolon is missing here 486 00:29:52.701 --> 00:29:54.687 Like so 487 00:29:55.000 --> 00:29:57.650 Now, this is quite simple, right? 488 00:29:57.651 --> 00:30:00.051 When you use this 489 00:30:00.051 --> 00:30:02.467 You can use it like this 490 00:30:02.467 --> 00:30:05.150 But if you look inside the content here 491 00:30:05.150 --> 00:30:07.650 It looks like this 492 00:30:07.651 --> 00:30:11.051 The key point is this 493 00:30:12.200 --> 00:30:16.050 Here, we have something called ActorIterator 494 00:30:16.051 --> 00:30:18.251 Which is an iterator 495 00:30:18.251 --> 00:30:21.750 In Unreal Engine, you can use such iterators 496 00:30:21.751 --> 00:30:23.751 To find objects Of the desired type 497 00:30:24.450 --> 00:30:30.200 That are present in the current level 498 00:30:30.200 --> 00:30:33.000 So actually, writing it this way is also a method 499 00:30:33.000 --> 00:30:41.000 Instead of using UGameplayStatics, let’s write it this way 500 00:30:41.550 --> 00:30:46.200 So, not using that, and instead, if we write another example, we do it like this 501 00:30:48.950 --> 00:30:52.650 instead of that, we use a for loop 502 00:30:52.650 --> 00:30:57.600 Then write TActorIterator 503 00:30:57.600 --> 00:30:59.700 And then what we want is 504 00:30:59.701 --> 00:31:04.201 We want to find APlayerPawn 505 00:31:05.550 --> 00:31:09.000 After that, we create an iterator with this 506 00:31:09.000 --> 00:31:13.100 At this point, make sure to include GetWorld here as well 507 00:31:15.850 --> 00:31:18.051 Since this is a repetition we use for 508 00:31:18.051 --> 00:31:22.151 This is how we write for line 509 00:31:24.000 --> 00:31:30.800 Next, if it is not null, 510 00:31:33.000 --> 00:31:36.000 Then you can write it like this 511 00:31:36.000 --> 00:31:38.000 Now we need to add the header 512 00:31:38.000 --> 00:31:43.000 Hold on a second, if you look here 513 00:31:43.000 --> 00:31:46.000 There is something called EngineUtils 514 00:31:46.000 --> 00:31:50.000 You should add that 515 00:31:50.000 --> 00:31:53.450 And EngineUtils looks like this 516 00:31:54.250 --> 00:31:56.800 Or you can search for it 517 00:31:56.800 --> 00:32:01.000 Similarly, if you search like this 518 00:32:01.000 --> 00:32:03.900 You can see information about headers 519 00:32:05.000 --> 00:32:07.700 It's formed like this 520 00:32:10.600 --> 00:32:14.000 Let's write it out exactly as it is because it's too long otherwise 521 00:32:14.000 --> 00:32:16.000 Let's proceed 522 00:32:16.000 --> 00:32:19.000 So once you've done that you can use this 523 00:32:19.000 --> 00:32:24.250 If you look, write APlayerPawn 524 00:32:24.250 --> 00:32:28.000 This will be the target 525 00:32:28.000 --> 00:32:32.000 The target is that the iterator is set up with double pointers 526 00:32:32.000 --> 00:32:39.650 So, you can insert the value into this pointer like this 527 00:32:40.750 --> 00:32:43.350 So, there are times that this could be null 528 00:32:43.350 --> 00:32:45.400 Because what it does is to keep searching 529 00:32:45.400 --> 00:32:49.450 Then, you check all the actors at that level thoroughly 530 00:32:49.450 --> 00:32:52.000 It's about finding one that matches this data type 531 00:32:52.000 --> 00:32:55.600 So, if it's null, you can just skip it 532 00:32:55.600 --> 00:32:58.000 If it is null, then 533 00:32:59.000 --> 00:33:02.000 Shall we write like this? 534 00:33:02.000 --> 00:33:04.000 if and nullptr 535 00:33:04.000 --> 00:33:08.300 In Unreal Engine, with C++ pointers, instead of checking for 536 00:33:08.300 --> 00:33:10.200 'Null' like this, please avoid doing so 537 00:33:10.200 --> 00:33:12.550 Please add ptr so it becomes nullptr 538 00:33:12.551 --> 00:33:14.651 You should check it like this 539 00:33:14.701 --> 00:33:18.450 Here, you can use continue 540 00:33:18.450 --> 00:33:22.000 Then, it will keep repeating until it succeeds 541 00:33:22.000 --> 00:33:24.000 Keep going until it’s finished, and then 542 00:33:24.000 --> 00:33:26.000 Then, if it succeeds 543 00:33:26.000 --> 00:33:32.150 Then, you can just do this task 544 00:33:35.250 --> 00:33:39.350 It would be good to remember that there are various methods like this 545 00:33:39.350 --> 00:33:43.000 Of course, you don’t need to master all of these yourself 546 00:33:43.000 --> 00:33:48.000 You can do it like this, or like this, or like this 547 00:33:48.000 --> 00:33:50.500 You can do this in whatever way is most comfortable for you 548 00:33:50.500 --> 00:33:53.000 The reason I'm explaining all of this is because 549 00:33:53.000 --> 00:33:56.000 When you're working on projects later 550 00:33:56.000 --> 00:33:58.600 You'll often need to read and understand 551 00:33:58.601 --> 00:34:00.101 Code written by others 552 00:34:00.101 --> 00:34:02.000 This is true in real world work environments 553 00:34:02.000 --> 00:34:06.000 In such cases, some people might have done it this way, and that's what I mean 554 00:34:06.000 --> 00:34:08.000 Since people work in various ways 555 00:34:08.000 --> 00:34:10.000 We need to be able to read that code 556 00:34:10.000 --> 00:34:14.000 So, that's why I'm introducing this to you 557 00:34:14.000 --> 00:34:20.050 Alright, then let's give it a try using this last one 558 00:34:25.100 --> 00:34:28.050 So like this 559 00:34:30.000 --> 00:34:32.150 That's done 560 00:34:37.600 --> 00:34:39.000 Let's compile it now 561 00:34:39.400 --> 00:34:42.550 Did I save it 562 00:34:43.650 --> 00:34:46.150 Compile it 563 00:34:47.000 --> 00:34:51.000 When we run it 564 00:34:51.650 --> 00:34:55.000 You can see it work the same 565 00:34:55.750 --> 00:34:58.200 But if this moves 566 00:34:58.200 --> 00:35:00.600 It feels a bit awkward when it comes exactly like this 567 00:35:00.600 --> 00:35:04.000 So, it would be nice to give it a little spin 568 00:35:04.650 --> 00:35:08.000 So, let's try rotate it 569 00:35:08.600 --> 00:35:10.900 If you look here 570 00:35:12.150 --> 00:35:15.000 To rotate it 571 00:35:15.000 --> 00:35:20.000 We can rotate in this direction 572 00:35:21.200 --> 00:35:27.000 Since we have set the direction in BeginPlay 573 00:35:27.000 --> 00:35:30.000 To this Direction 574 00:35:30.000 --> 00:35:34.750 I want to rotate 575 00:35:40.000 --> 00:35:42.300 In the direction 576 00:35:42.301 --> 00:35:43.751 I want to make this happen 577 00:35:44.300 --> 00:35:46.950 For rotating, you can apply various methods 578 00:35:46.951 --> 00:35:48.751 The simplest of all is 579 00:35:48.752 --> 00:35:50.052 Using this 580 00:35:50.052 --> 00:35:52.000 Let's go to blueprint 581 00:35:52.000 --> 00:35:58.600 If you look here, you can find a series of Make Rot from 582 00:35:58.600 --> 00:36:01.600 This one means, will look toward the direction 583 00:36:01.601 --> 00:36:02.901 You can think of it like this 584 00:36:02.901 --> 00:36:04.950 IF you use Make Rot from X 585 00:36:04.951 --> 00:36:08.151 It means setting the X direction to a certain direction 586 00:36:08.501 --> 00:36:11.050 Now, there is a single one and XYZ coordinates 587 00:36:11.051 --> 00:36:14.351 There are also coordinates like XY, XZ, and so on 588 00:36:14.351 --> 00:36:19.000 What it means is, for example 589 00:36:23.300 --> 00:36:26.350 Let's say there is an object that looks like this 590 00:36:26.351 --> 00:36:28.051 This side is the front 591 00:36:29.051 --> 00:36:33.150 Instead of looking at it this way, consider that our airplane is oriented like this 592 00:36:33.151 --> 00:36:35.401 Let's say it's like this here 593 00:36:37.800 --> 00:36:42.250 So, this one is going in this direction 594 00:36:42.250 --> 00:36:45.150 So, it is saying that it’ll rotate 595 00:36:45.151 --> 00:36:46.851 To face this direction and where it's headed is 596 00:36:47.152 --> 00:36:49.002 That it is moving forward 597 00:36:49.002 --> 00:36:50.551 Since this is rotated 598 00:36:50.551 --> 00:36:52.901 Let's say our protagonist 599 00:36:54.800 --> 00:36:57.600 Moved aside like this 600 00:36:57.600 --> 00:37:02.000 Now, it can set the direction like this 601 00:37:02.000 --> 00:37:05.850 So, currently 602 00:37:05.851 --> 00:37:06.851 It comes like this 603 00:37:06.852 --> 00:37:08.652 Even if you set the direction in this state 604 00:37:08.653 --> 00:37:10.603 It still comes down like this 605 00:37:10.603 --> 00:37:12.401 I don't want to rotate it like this 606 00:37:12.401 --> 00:37:15.301 Instead, what I want is 607 00:37:15.302 --> 00:37:18.252 For it to rotate like this 608 00:37:18.252 --> 00:37:21.000 Let's say we view it from the side 609 00:37:21.000 --> 00:37:24.250 So, the direction it’s moving is this way 610 00:37:24.251 --> 00:37:26.651 This is what it looks like now 611 00:37:27.300 --> 00:37:30.300 Let's assume this direction is the front 612 00:37:30.300 --> 00:37:32.000 Then this side is up 613 00:37:32.900 --> 00:37:35.300 Then I'm going this way 614 00:37:35.301 --> 00:37:37.901 For example, if it rotates like this 615 00:37:38.100 --> 00:37:41.100 It might not show here, but let's assume it has rotated anyway 616 00:37:41.100 --> 00:37:43.300 So, if it moves in this direction 617 00:37:43.301 --> 00:37:45.851 Moving like this also means it's going in this direction 618 00:37:47.000 --> 00:37:48.500 Even when it’s in an inverted state 619 00:37:48.501 --> 00:37:49.701 Moving like this still means it’s going in this direction 620 00:37:50.000 --> 00:37:52.950 These two situations are the same 621 00:37:52.951 --> 00:37:53.951 The goal is the same 622 00:37:54.000 --> 00:37:58.000 However, if it rotates in a certain way, that wouldn't work 623 00:37:58.000 --> 00:38:02.400 Right, so we'll keep the top of the object fixed 624 00:38:02.401 --> 00:38:04.351 And only rotate the front 625 00:38:04.351 --> 00:38:08.000 When doing this, you use these two components 626 00:38:10.150 --> 00:38:13.150 Use make, route, and from 627 00:38:13.500 --> 00:38:16.750 So, the second one is the fixed axis 628 00:38:16.750 --> 00:38:21.000 Think of the first value for the front is the rotation axis 629 00:38:21.000 --> 00:38:24.400 Think of it not as the axis of rotation but as the direction of rotation 630 00:38:24.400 --> 00:38:27.650 The second one refers to the fixed axis 631 00:38:27.650 --> 00:38:31.750 In that case, from our perspective here 632 00:38:31.751 --> 00:38:33.401 We want to fix the top side 633 00:38:33.401 --> 00:38:35.300 Keep the top side as it is 634 00:38:35.301 --> 00:38:38.101 So, we want to ensure that this area remains the top 635 00:38:38.651 --> 00:38:42.450 So, we want this area to be the top while this part rotates like this 636 00:38:42.450 --> 00:38:44.750 So, whether we look this way or that way 637 00:38:44.750 --> 00:38:49.000 The axis we want to fix would be the top axis 638 00:38:49.800 --> 00:38:55.000 So, we’ll use this 639 00:38:55.000 --> 00:38:59.550 Then, with MakeRotFromX 640 00:38:59.550 --> 00:39:01.850 Since I'm dealing with the front side, I'll use X for the rotation 641 00:39:01.851 --> 00:39:04.701 Since the fixed axis is the top, it would be Z 642 00:39:05.000 --> 00:39:09.000 So, we have two arguments here, with these two values 643 00:39:09.000 --> 00:39:11.600 The direction and the fixed axis 644 00:39:11.600 --> 00:39:13.000 Like so 645 00:39:13.000 --> 00:39:14.900 If you double click this 646 00:39:14.901 --> 00:39:16.901 We have them again, very convenient 647 00:39:16.901 --> 00:39:22.000 Looking at it, you'll find that it’s in the UKismetMathLibrary 648 00:39:22.000 --> 00:39:26.200 By using this, you can easily perform rotations 649 00:39:26.200 --> 00:39:29.750 This means you can use this function here 650 00:39:29.750 --> 00:39:33.000 Then, we need to add the header for this 651 00:39:33.000 --> 00:39:37.400 Similarly, if you search here 652 00:39:40.250 --> 00:39:43.250 You’ll find that this is also in Kismet 653 00:39:44.150 --> 00:39:47.600 Let's break it down 654 00:39:50.700 --> 00:39:54.300 First, add this, and then 655 00:39:59.450 --> 00:40:01.200 Once you do this, you'll be able to use it 656 00:40:01.200 --> 00:40:04.901 Then, if you look here and open the parentheses 657 00:40:04.901 --> 00:40:06.000 You'll see that there are two arguments 658 00:40:06.000 --> 00:40:07.700 They are x and z 659 00:40:07.700 --> 00:40:09.400 x is direction 660 00:40:09.401 --> 00:40:12.051 The direction where I want to go toward 661 00:40:12.051 --> 00:40:15.300 Next, what’s the axis you want to fix? 662 00:40:15.301 --> 00:40:16.951 It's UpVector 663 00:40:18.000 --> 00:40:24.700 So, you should use GetActorUpVector 664 00:40:25.350 --> 00:40:28.750 And add UpVector 665 00:40:30.500 --> 00:40:33.000 Just using this doesn’t fix it 666 00:40:33.001 --> 00:40:34.101 It won’t rotate just by using this 667 00:40:34.102 --> 00:40:35.300 You need to actually perform the rotation 668 00:40:35.300 --> 00:40:37.300 This is just obtaining the direction 669 00:40:37.300 --> 00:40:39.750 So, as you can see here 670 00:40:39.751 --> 00:40:44.101 It returns the result as a specific data type 671 00:40:44.101 --> 00:40:47.651 So, let's define the new rotation 672 00:40:47.651 --> 00:40:51.251 Using FRotator here 673 00:40:51.251 --> 00:40:55.000 Then, you need to use this as the new rotation 674 00:40:55.000 --> 00:41:00.450 Then, use SetActorRotation to apply it 675 00:41:00.451 --> 00:41:02.851 Write newRotation here 676 00:41:02.852 --> 00:41:04.652 And it will apply the rotation 677 00:41:09.000 --> 00:41:10.050 Save 678 00:41:10.051 --> 00:41:12.701 After compiling 679 00:41:13.000 --> 00:41:15.800 Oh, I'll remove this one 680 00:41:17.100 --> 00:41:20.600 Now, compile 681 00:41:24.000 --> 00:41:27.000 Let’s run it, Like this 682 00:41:27.650 --> 00:41:31.000 As you can see, it rotates immediately 683 00:41:31.250 --> 00:41:33.150 When going down, it moves straightforwardly 684 00:41:33.151 --> 00:41:35.951 And when you do it this way, it rotates 685 00:41:38.650 --> 00:41:43.000 To make sure it’s flipping correctly 686 00:41:43.000 --> 00:41:46.500 Let’s apply an asset and check it out 687 00:41:48.000 --> 00:41:50.200 We have an asset we created 688 00:41:50.201 --> 00:41:52.301 This spaceship is the main character 689 00:41:52.302 --> 00:41:54.952 The drone can be used as the enemy 690 00:41:55.000 --> 00:41:58.000 So, let's include this asset here 691 00:41:58.000 --> 00:42:01.000 Make a folder 692 00:42:02.000 --> 00:42:08.000 I'll create a folder named models 693 00:42:08.000 --> 00:42:13.350 Then, I'll place these two files directly into that folder 694 00:42:14.000 --> 00:42:16.600 Import all 695 00:42:18.000 --> 00:42:20.000 It’s been added correctly 696 00:42:20.750 --> 00:42:23.250 I’ll go ahead and set up the drone now 697 00:42:23.251 --> 00:42:24.901 Right now, it looks like this 698 00:42:24.902 --> 00:42:26.802 Save for now 699 00:42:29.450 --> 00:42:33.000 This is the mesh, and it’s set as a static mesh 700 00:42:33.000 --> 00:42:34.850 Next, this is the material 701 00:42:34.851 --> 00:42:36.751 This material is applied 702 00:42:36.752 --> 00:42:38.002 And it's showing up in pink 703 00:42:38.002 --> 00:42:39.953 It seems like the connection might be broken 704 00:42:40.000 --> 00:42:42.800 So, I’ll recreate this again 705 00:42:42.801 --> 00:42:44.751 Let's delete this 706 00:42:52.000 --> 00:42:54.700 Here, you can see several options 707 00:42:54.701 --> 00:42:56.851 Here, there are normals 708 00:42:58.700 --> 00:43:04.000 There are two options for metallic and smooth 709 00:43:04.000 --> 00:43:08.000 There's metallic, smooth, emissive 710 00:43:08.000 --> 00:43:10.950 And basic color 711 00:43:10.950 --> 00:43:12.900 Here, you can see the base color 712 00:43:12.901 --> 00:43:16.351 Connect the base color here like this 713 00:43:20.000 --> 00:43:23.000 And then, next 714 00:43:23.000 --> 00:43:25.750 You'll see the normal 715 00:43:25.751 --> 00:43:29.701 You can connect the normal here 716 00:43:32.200 --> 00:43:37.000 Normals usually have colors like blue or purple 717 00:43:37.000 --> 00:43:43.000 Then, this is labeled as metallic and smooth 718 00:43:43.000 --> 00:43:46.050 Typically, metallic is here 719 00:43:46.051 --> 00:43:49.001 And smoothness is referred to as roughness 720 00:43:49.051 --> 00:43:51.850 These are stored in the R and G channels 721 00:43:51.851 --> 00:43:53.751 So, assign the metallic to the R channel 722 00:43:53.752 --> 00:43:57.402 And roughness to the G channel 723 00:43:57.402 --> 00:43:59.450 Next, this is the emissive 724 00:43:59.450 --> 00:44:01.450 IT says emissive here 725 00:44:01.451 --> 00:44:05.401 Here, you can see the emissive color 726 00:44:05.402 --> 00:44:07.202 I'll place the emissive color here 727 00:44:07.202 --> 00:44:09.200 Now, the color has changed like this 728 00:44:09.201 --> 00:44:11.651 Save now 729 00:44:12.400 --> 00:44:14.951 If you look at the drone, the color's different 730 00:44:14.951 --> 00:44:18.551 This is a bit of an homage to Star Wars 731 00:44:19.000 --> 00:44:22.350 This was created by our art instructor 732 00:44:22.351 --> 00:44:24.801 So, we have the license 733 00:44:24.801 --> 00:44:28.000 I’ll go ahead and use this 734 00:44:29.950 --> 00:44:32.450 Let's open the Enemy for a moment. 735 00:44:32.451 --> 00:44:35.401 The Enemy mesh is currently a box, a cube 736 00:44:35.402 --> 00:44:38.102 Let's replace that with the asset called drone 737 00:44:38.102 --> 00:44:42.000 I'll replace it with the drone 738 00:44:42.950 --> 00:44:44.450 replace it like this 739 00:44:44.451 --> 00:44:46.551 Then, it will change like this 740 00:44:46.801 --> 00:44:50.750 To go back, you can do this, and it will be updated accordingly 741 00:44:50.750 --> 00:44:55.000 After that, we’ll set the position like this 742 00:44:56.050 --> 00:45:00.150 This way is the front side 743 00:45:00.151 --> 00:45:03.051 Let's rotate it so that it faces forward 744 00:45:03.101 --> 00:45:04.500 The shorter side is the front 745 00:45:04.501 --> 00:45:06.751 Thus, rotate it like this 746 00:45:07.000 --> 00:45:08.350 I’ll position it like this 747 00:45:08.351 --> 00:45:11.151 Let's place it Inside the cube 748 00:45:11.152 --> 00:45:13.652 Within the box collision object 749 00:45:15.250 --> 00:45:20.850 Currently, the size doesn’t quite match, so to fix this you can adjust it 750 00:45:21.300 --> 00:45:25.000 By viewing from the top and using the scale 751 00:45:36.900 --> 00:45:39.000 I'll increase the size a bit to make it look better 752 00:45:39.450 --> 00:45:42.450 That's that 753 00:45:44.600 --> 00:45:46.701 While we're at it, let's also adjust the protagonist 754 00:45:46.701 --> 00:45:49.251 Open the spaceship 755 00:45:49.600 --> 00:45:54.000 It looks like this 756 00:45:54.850 --> 00:45:58.800 Let’s go to the spaceship and change the texture to this one 757 00:45:58.801 --> 00:46:01.151 All of these 758 00:46:01.601 --> 00:46:04.350 Drag and drop 759 00:46:05.000 --> 00:46:07.450 The top one 760 00:46:09.350 --> 00:46:10.850 This one is the base color 761 00:46:10.851 --> 00:46:13.951 Connect the base color like this 762 00:46:15.500 --> 00:46:19.650 This blue one is the normal 763 00:46:21.000 --> 00:46:26.000 Connect it accordingly 764 00:46:27.000 --> 00:46:30.600 Next, the dark one here is the emissive 765 00:46:30.601 --> 00:46:33.351 Connect the emissive here 766 00:46:34.000 --> 00:46:37.260 Here, you can see 767 00:46:37.260 --> 00:46:40.800 It's set up with Occlusion, Roughness, and Metallic 768 00:46:40.800 --> 00:46:43.450 Occlusion Roughness Metalic 769 00:46:43.451 --> 00:46:46.851 This is Ambient Occlusion 770 00:46:47.300 --> 00:46:49.550 And then roughness 771 00:46:49.551 --> 00:46:52.001 Then, add the Metallic here like this 772 00:46:52.800 --> 00:46:56.900 This will properly configure the colors 773 00:46:58.350 --> 00:47:03.000 This will also correctly apply to the main character 774 00:47:07.700 --> 00:47:11.100 If you look closely, you’ll see that the license is 775 00:47:11.101 --> 00:47:13.851 Listed as ARA XR Lab 776 00:47:13.851 --> 00:47:17.000 This is also something we created 777 00:47:17.000 --> 00:47:19.801 The copyright belongs to us 778 00:47:19.801 --> 00:47:22.651 Let's use this to proceed 779 00:47:22.651 --> 00:47:25.400 Double click the main character 780 00:47:25.401 --> 00:47:27.251 And make changes in the same way 781 00:47:27.251 --> 00:47:29.400 Our protagonist is facing up 782 00:47:29.401 --> 00:47:36.201 So the name here is the spaceship 783 00:47:39.000 --> 00:47:40.600 Place it like this 784 00:47:40.601 --> 00:47:44.651 Since this is a bit small, let's make it bigger 785 00:47:44.651 --> 00:47:48.200 Change the color here in the same way 786 00:47:53.200 --> 00:47:58.000 It should look good from the back view 787 00:47:58.000 --> 00:48:00.700 Like so 788 00:48:00.701 --> 00:48:03.251 Let's rotate a bit 789 00:48:08.400 --> 00:48:11.400 Let's check and rotate it from here for now 790 00:48:11.750 --> 00:48:15.000 We need to make sure it faces this way 791 00:48:15.300 --> 00:48:20.000 Let's rotate it like this 792 00:48:22.000 --> 00:48:24.400 Let's look at it at a back view 793 00:48:24.400 --> 00:48:29.000 And then try to fit it in the box 794 00:48:29.000 --> 00:48:30.700 This should be good to go now 795 00:48:30.701 --> 00:48:35.051 Now, let's compile and play 796 00:48:35.051 --> 00:48:39.000 We can set it up like this 797 00:48:40.251 --> 00:48:42.977 Creating Enemy Spawner 798 00:48:44.250 --> 00:48:48.000 Now, let's create an enemy 799 00:48:48.700 --> 00:48:50.600 We'll create an enemy spawner 800 00:48:50.601 --> 00:48:53.651 We’ll create a new class 801 00:48:53.701 --> 00:48:56.000 And make an actor here as well 802 00:48:56.000 --> 00:48:57.950 Now next 803 00:48:57.951 --> 00:49:03.451 Let's name this EnemyManagerActor 804 00:49:06.100 --> 00:49:08.550 Create class 805 00:49:13.200 --> 00:49:14.950 In the last session 806 00:49:14.951 --> 00:49:17.601 we worked on firing automatically 807 00:49:17.601 --> 00:49:22.000 So, we set up the gun to fire bullets at frequent intervals 808 00:49:22.000 --> 00:49:25.000 We can do a similar thing here as well 809 00:49:26.900 --> 00:49:29.650 So, after a certain amount of time has passed 810 00:49:29.651 --> 00:49:30.951 It will spawn an enemy 811 00:49:30.952 --> 00:49:33.102 This will be the basic concept 812 00:49:35.650 --> 00:49:39.650 So, let's go to manager's header 813 00:49:43.800 --> 00:49:46.050 We don’t need to worry about the appearance for this 814 00:49:46.051 --> 00:49:48.251 Only thing we need to do is just to place objects 815 00:49:48.551 --> 00:49:52.400 First, time flows 816 00:49:53.401 --> 00:49:56.001 And then after certain amount of time 817 00:49:57.200 --> 00:50:01.100 Spawns an enemy 818 00:50:01.601 --> 00:50:03.501 And place it at a certain point 819 00:50:03.501 --> 00:50:05.350 Arrow will make it more convenient 820 00:50:05.350 --> 00:50:10.350 Place the Spawned creature at arrow's position 821 00:50:10.901 --> 00:50:13.101 Let's set it up like this 822 00:50:13.701 --> 00:50:19.350 To do this, first we need to use UPROPERTY 823 00:50:25.600 --> 00:50:27.600 EditAnywhere 824 00:50:27.600 --> 00:50:32.000 Next, we'll need to place an arrow component 825 00:50:32.000 --> 00:50:34.500 However, you shouldn't place the arrow directly on the root 826 00:50:34.501 --> 00:50:38.151 Because the arrow needs to be rotated and transformed 827 00:50:38.151 --> 00:50:42.000 So, we'll first create a parent component 828 00:50:42.000 --> 00:50:45.000 Here, there's one more thing to explain 829 00:50:45.600 --> 00:50:49.200 For components 830 00:50:49.201 --> 00:50:52.001 There is actor component 831 00:50:56.000 --> 00:51:00.000 And there is also a SceneComponent which inherits from them 832 00:51:04.900 --> 00:51:13.100 There’s also a PrimitiveComponent that inherits from SceneComponent 833 00:51:13.100 --> 00:51:14.400 So these are components 834 00:51:14.401 --> 00:51:18.151 In blueprint, it creates these two 835 00:51:18.151 --> 00:51:20.700 In C++, you can use this one 836 00:51:20.701 --> 00:51:23.001 But basically these two are used often 837 00:51:23.001 --> 00:51:25.450 So, the main difference between an actor and a scene component is 838 00:51:25.450 --> 00:51:30.900 That this Actor component has no transform 839 00:51:30.901 --> 00:51:33.251 But the Scene component has it 840 00:51:33.251 --> 00:51:34.050 The big difference is this 841 00:51:34.051 --> 00:51:36.050 A SceneComponent can be placed in a scene 842 00:51:36.050 --> 00:51:39.850 Which essentially refers 843 00:51:39.851 --> 00:51:44.801 To a space like a world or level 844 00:51:44.801 --> 00:51:46.600 So, it’s structured like this 845 00:51:46.601 --> 00:51:48.301 In reality, the terminology can be quite mixed and overlapping 846 00:51:48.351 --> 00:51:51.600 Strictly speaking, a level is a concept contained within a world 847 00:51:51.600 --> 00:51:55.000 But you can think of a scene as being synonymous with a level 848 00:51:55.000 --> 00:51:57.550 Since it can be placed in a scene 849 00:51:57.551 --> 00:52:00.251 It has a transform associated with it 850 00:52:01.700 --> 00:52:03.050 The transform is required 851 00:52:03.051 --> 00:52:05.751 For us to be able to utilize 852 00:52:05.752 --> 00:52:07.852 Location, rotation and scale 853 00:52:07.852 --> 00:52:11.000 So, it’s structured this way and the PrimitiveComponent is placed here 854 00:52:11.000 --> 00:52:14.600 he PrimitiveComponent includes a transform 855 00:52:14.601 --> 00:52:18.451 And it also handles collision and overlap functionalities 856 00:52:18.451 --> 00:52:22.950 You can think of it as a component that handles all of those functionalities 857 00:52:22.950 --> 00:52:25.750 So, hope you keep this in mind as you learn 858 00:52:25.750 --> 00:52:27.600 So, since I’m going to be placing it 859 00:52:27.601 --> 00:52:30.201 I’ll create a SceneComponent 860 00:52:32.700 --> 00:52:37.450 Components start with U so we'll use USceneComponent 861 00:52:37.450 --> 00:52:42.300 Let's name this Root 862 00:52:42.300 --> 00:52:48.350 And then RootComp 863 00:52:50.400 --> 00:52:54.000 And then I'll make the arrow 864 00:52:54.000 --> 00:53:00.500 Declare it as class UArrowComponent 865 00:53:06.800 --> 00:53:08.200 And we need to do this as well 866 00:53:08.201 --> 00:53:10.501 Time will flow 867 00:53:10.551 --> 00:53:16.500 First, let's declare float CurrentTime 868 00:53:16.500 --> 00:53:18.000 We need to have current time 869 00:53:18.001 --> 00:53:21.101 And then float 870 00:53:24.000 --> 00:53:27.400 We also need something like MakeTime 871 00:53:27.400 --> 00:53:29.051 The program is slow 872 00:53:29.051 --> 00:53:30.451 Let's wait for a bit 873 00:53:31.000 --> 00:53:33.550 Okay MakeTime 874 00:53:35.800 --> 00:53:38.350 Set the time interval to 1 or 2 seconds for MakeTime 875 00:53:38.351 --> 00:53:40.351 So 1 enemy would spawn every two seconds 876 00:53:40.951 --> 00:53:42.450 To spawn enemies 877 00:53:42.451 --> 00:53:45.501 We need to have a UClass for the enemy 878 00:53:45.601 --> 00:53:49.000 Then, you can use TSubclassOf to create it 879 00:53:49.000 --> 00:53:52.450 "Make sure to use UPROPERTY 880 00:53:52.450 --> 00:53:54.600 With EditAnywhere 881 00:53:54.601 --> 00:53:59.951 Next, use TSubclassOf 882 00:54:01.000 --> 00:54:06.700 And then write AEnemyActor 883 00:54:06.700 --> 00:54:11.400 Them, EnemyFactory 884 00:54:11.400 --> 00:54:15.000 Set it up like this 885 00:54:17.850 --> 00:54:21.050 Now we have to work on this 886 00:54:21.050 --> 00:54:25.000 Come to the constructor, and first, create the root component 887 00:54:25.000 --> 00:54:29.000 Since the name Root might be conflicting, we should choose a different name 888 00:54:29.000 --> 00:54:34.000 Let's name it RootSceneComponent for clarity 889 00:54:34.000 --> 00:54:38.000 That seems like a good choice to avoid confusion 890 00:54:38.000 --> 00:54:41.000 We've used root component 891 00:54:41.000 --> 00:54:43.400 Let's use RootSceneComp 892 00:54:43.400 --> 00:54:45.000 Like so 893 00:54:45.000 --> 00:54:50.000 Use CreateDefaultSubobject 894 00:54:50.000 --> 00:54:52.500 Name it exactly as RootSceneComponent 895 00:54:56.850 --> 00:54:59.850 Here, use USceneComponent 896 00:55:00.000 --> 00:55:03.600 Then, set the name to RootSceneComponent exactly as is 897 00:55:04.750 --> 00:55:11.000 Write SetRoot like this 898 00:55:13.000 --> 00:55:17.000 And now we need to make Arrow 899 00:55:19.350 --> 00:55:22.000 Then create, just like before 900 00:55:22.200 --> 00:55:24.200 Like so 901 00:55:30.500 --> 00:55:33.000 Arrow component goes here as well 902 00:55:34.450 --> 00:55:37.600 UArrow component here 903 00:55:38.000 --> 00:55:41.000 Now you need to add the header 904 00:55:44.800 --> 00:55:47.100 Since SceneComponent was inherited 905 00:55:47.100 --> 00:55:49.350 I mean since it is already included 906 00:55:49.350 --> 00:55:51.000 you can just use it 907 00:55:51.000 --> 00:55:52.800 Now we need to add it 908 00:55:52.800 --> 00:55:56.200 Now attach it to the root 909 00:55:56.200 --> 00:55:59.000 SetUpAttachment 910 00:55:59.600 --> 00:56:02.600 I’ll set it up as RootSceneComponent 911 00:56:07.150 --> 00:56:09.150 Now we need to make it 912 00:56:09.150 --> 00:56:10.000 Make the time flow 913 00:56:10.000 --> 00:56:11.850 We can do that with Tick 914 00:56:11.850 --> 00:56:15.650 First of all, the first timer will be set 915 00:56:15.650 --> 00:56:21.900 Secondly, when it becomes spawn time 916 00:56:23.400 --> 00:56:29.800 Third, spawn enemy at arrow 917 00:56:30.850 --> 00:56:32.300 I want to spawn it 918 00:56:32.300 --> 00:56:34.250 Where? At arrow 919 00:56:34.250 --> 00:56:36.650 Arrow's Transfrom 920 00:56:39.200 --> 00:56:43.250 Like so, and reset 921 00:56:45.000 --> 00:56:49.600 Current time to 0 922 00:56:49.600 --> 00:56:52.250 Write it up like this 923 00:56:52.250 --> 00:56:53.000 Let's start one by one 924 00:56:53.000 --> 00:56:55.000 CurrentTime 925 00:56:57.000 --> 00:57:00.300 Amd DeltaTime 926 00:57:00.300 --> 00:57:02.000 Let's say if 927 00:57:04.750 --> 00:57:08.700 CurrentTime equals MakeTime 928 00:57:12.400 --> 00:57:14.400 Then, you should spawn the enemy 929 00:57:14.400 --> 00:57:16.750 Place Spawn at GetWorld line 930 00:57:16.750 --> 00:57:18.200 GetWorld 931 00:57:18.200 --> 00:57:21.000 Since we did this before, I’ll quickly go through the setup 932 00:57:23.650 --> 00:57:25.650 GetWorld 933 00:57:26.300 --> 00:57:28.000 Then SpawnActor 934 00:57:28.000 --> 00:57:30.000 And then 935 00:57:30.000 --> 00:57:33.000 The object we want to make using Template 936 00:57:33.000 --> 00:57:34.650 Is the enemy 937 00:57:34.650 --> 00:57:36.000 EnemyActor 938 00:57:37.000 --> 00:57:38.000 It will make this 939 00:57:38.000 --> 00:57:42.000 And then the header must be added 940 00:57:44.000 --> 00:57:46.650 Let’s divide the view at the top and take a look 941 00:57:46.650 --> 00:57:49.800 For the top part 942 00:57:49.800 --> 00:57:52.650 The header has been added 943 00:57:58.334 --> 00:58:00.084 And then 944 00:58:00.350 --> 00:58:01.550 Here 945 00:58:02.896 --> 00:58:04.596 There are two things 946 00:58:04.650 --> 00:58:05.700 That go in here 947 00:58:05.701 --> 00:58:07.042 UClass 948 00:58:07.042 --> 00:58:09.200 The UClass we made 949 00:58:09.201 --> 00:58:12.131 Is the Factory that is made of TSubclass 950 00:58:12.131 --> 00:58:15.350 So put that in here 951 00:58:16.151 --> 00:58:20.750 And then in the ArrowComp 952 00:58:20.750 --> 00:58:23.500 Add GetComponentTransform 953 00:58:25.700 --> 00:58:29.250 Place it like this 954 00:58:30.250 --> 00:58:32.640 Also, we need to reset CurrentTime 955 00:58:32.640 --> 00:58:38.000 Set CurrentTime to 0 956 00:58:44.000 --> 00:58:46.000 And then 957 00:58:46.450 --> 00:58:48.450 Save all now 958 00:58:49.850 --> 00:58:52.850 Go to the Unreal Editor and compile 959 00:58:55.150 --> 00:58:56.850 We can see it working well 960 00:58:56.850 --> 00:58:59.900 Remove the enemy for now 961 00:58:59.900 --> 00:59:01.800 Let's take it out 962 00:59:01.800 --> 00:59:05.650 Next, set up the EnemyActor 963 00:59:05.650 --> 00:59:06.650 I mean the manager 964 00:59:06.650 --> 00:59:08.650 We need to position the manager here 965 00:59:08.650 --> 00:59:11.000 "I'll create and place this as a Blueprint 966 00:59:11.000 --> 00:59:12.450 Like this 967 00:59:12.450 --> 00:59:16.500 Write BP 968 00:59:17.850 --> 00:59:19.850 You can see the Arrow like this 969 00:59:19.850 --> 00:59:23.050 We need to rotate it 970 00:59:23.050 --> 00:59:25.100 Like so 971 00:59:25.100 --> 00:59:26.600 We are looking at it like this 972 00:59:26.600 --> 00:59:28.600 Did we set this 973 00:59:28.600 --> 00:59:31.000 To 180 and minus 90 earlier 974 00:59:31.000 --> 00:59:32.650 Like this 975 00:59:32.650 --> 00:59:34.250 Rotate it 976 00:59:34.250 --> 00:59:35.500 And then 977 00:59:35.500 --> 00:59:37.000 Let's place it 978 00:59:37.000 --> 00:59:39.350 Shall we place it here like this? 979 00:59:39.350 --> 00:59:40.800 Place it in the middle first 980 00:59:40.800 --> 00:59:42.750 And move it up a bit 981 00:59:42.750 --> 00:59:45.000 And then like this 982 00:59:45.000 --> 00:59:47.000 You can input Ctrl and D to replicate 983 00:59:47.000 --> 00:59:49.000 After copying it 984 00:59:49.000 --> 00:59:52.000 Place 5 of the copies 985 00:59:52.000 --> 00:59:54.450 Place them like this 986 00:59:54.500 --> 00:59:58.000 Make sure all of these are selected 987 00:59:58.000 --> 01:00:00.850 And set the X value to 0 988 01:00:02.100 --> 01:00:04.750 Front and back should be 0 989 01:00:04.750 --> 01:00:07.000 And then let's play it 990 01:00:07.000 --> 01:00:08.000 Wait not yet 991 01:00:08.000 --> 01:00:11.400 We need to fill the factory 992 01:00:11.400 --> 01:00:13.000 After doing all that 993 01:00:13.000 --> 01:00:16.000 Replace the default factory part 994 01:00:16.000 --> 01:00:18.700 with BP EnemyActor here 995 01:00:18.700 --> 01:00:20.600 Now compile 996 01:00:20.600 --> 01:00:23.450 And then play it 997 01:00:23.450 --> 01:00:25.000 The enemies are spawning 998 01:00:25.000 --> 01:00:27.000 Every two seconds 999 01:00:27.000 --> 01:00:29.000 Five of them all at once 1000 01:00:29.000 --> 01:00:31.000 flying towards the player 1001 01:00:32.000 --> 01:00:34.000 That's it for today 1002 01:00:35.000 --> 01:00:39.000 Let's summarize what we've covered in this session 1003 01:00:39.151 --> 01:00:40.151 Creating and Orienting Enemies Creating Enemies Facing Forward Create a new Actor class and name it EnemyActor 1004 01:00:40.152 --> 01:00:41.152 Declare the collision component as UBoxComponent* BoxComp Declare the visual component as UStaticMeshComponent* MeshComp 1005 01:00:41.153 --> 01:00:42.353 Create the BoxComp with CreateDefaultSubobject UBoxComponent TEXT() 1006 01:00:42.353 --> 01:00:43.354 Create the MeshComp with CreateDefaultSubobject UStaticMeshComponent TEXT() 1007 01:00:43.354 --> 01:00:44.304 Set the actor's location using SetActorLocation P0 plus Direction times Speed times DeltaTime Create and place the Enemy actor using Blueprint 1008 01:00:44.304 --> 01:00:45.355 Random Direction Determination Feature Method 1: GetPlayerPawn function Method 2: GetActorOfClass fucntion 1009 01:00:45.355 --> 01:00:46.556 Method 3: Use a TActorIterator loop 1010 01:00:46.557 --> 01:00:48.207 Creating an Enemy Spawner Function to Spawn Enemies at Regular Intervals Create a new Actor class and name it EnemyManagerActor 1011 01:00:48.207 --> 01:00:49.558 Declared USceneComponent RootComp Declared UArrowComponent ArrowComp 1012 01:00:49.558 --> 01:00:51.809 Created RootSceneComp with CreateDefaultSubobject TEXT() Created ArrowComp with CreateDefaultSubobject TEXT () 1013 01:00:51.809 --> 01:00:53.810 Declared and implemented the Tick function with DeltaTime 1014 01:00:53.810 --> 01:00:54.810 The End