‫Hey.
‫Welcome back.
‫Now we know that we need to get the hit result under the cursor.
‫We're going to talk a little bit more about how that works and what that means in this video.
‫So our goal is to get the hit results under the cursor and show this location, and we can do so by
‫drawing a debug sphere.
‫We'll learn how to do that as well.
‫So let's talk about something called a hit result.
‫In games will often want to do something like this.
‫We'll have a point in space.
‫We'll call this point start and it has the type F vector and we'll have an end location.
‫This will also be a point in space of type F vector.
‫Now let's say we'd like to draw an invisible line from the start point to the end point.
‫And at the moment we draw this line, we'd like to see if there are any objects in between the start
‫and end locations.
‫Now, if there are, then this line that we're drawing in space is going to hit that object.
‫On the surface, when this happens, we call this a hit event.
‫Now, when we draw an invisible line like this, it's called performing a line trace.
‫And when we hit something, we say that we have a trace hit.
‫Now, if we do hit something and get a hit event, then the trace hit stores information in a struct
‫called a hit result.
‫Its type is F hit result.
‫Now the F hit results struct contains variables that store information about the hit event, including
‫the hit location as an f vector in space and the actor that we hit, among other information.
‫Now, when we perform a line trace, we do so by specifying a collision channel.
‫Usually with line traces, we choose the channel called visibility.
‫There exists an enum called E Collision Channel, and in this enum there's an enum constant called XY
‫visibility.
‫This is one of the parameters we specify when performing a line trace.
‫Now, if we specify the visibility channel, that means objects that are set to block the visibility
‫channel in their collision settings will register hit events.
‫Any objects that are not set to block the visibility channel will not generate hit events.
‫Now we would like the trace result under the cursor.
‫Imagine we have the screen here and here's our cursor now.
‫At the tip of our cursor, we have a point on the screen when we use the function to get the hit result
‫under the cursor.
‫What happens is we have our camera and it may see some objects in the world, such as the floor here.
‫And we're performing a line trace from the camera at the point on the screen corresponding to our cursor
‫location, and we're shooting the line trace straight out into the world.
‫And if we hit something, we'll generate a hit event and store the information in a hit result struct.
‫So let's find out how we can do this.
‫I'm here in tank CP and what I'd like to do is get the hit result under the cursor every frame, which
‫means we need the tick function.
‫So again, we're going back into base upon and finding our tick function here.
‫Now we're not using it for anything in base pawn so we can move this function into the tank class just
‫like we did with Begin Play.
‫So I'm going to highlight the function declaration along with its comment and copy it.
‫And after that I'll delete this whole section, public and all, and then I'll go back into Tank H and
‫here in the public section I'm going to paste the tick function declaration.
‫Now we're not using it in base pawn, so I'm going to remove the tick function from base pont.
‫CP Now it's gone from base pawn.
‫Now we have it here declared intent, but we also need to define the function in tank.
‫CP I'm going to do it here in tank DHCP, just under setup player input component.
‫So we're going to say void tick.
‫It takes a float called Delta Time.
‫And there's our body.
‫Now again, we need a tank just before the tick function, along with the scope resolution operator.
‫And we also need to call super tick and pass in Delta time.
‫So we now have tick on the tank class.
‫What we want to do is get the hit results under the cursor.
‫So here's how we do it.
‫The function we're going to use exists on the player controller called get hit result under cursor.
‫We've been talking about this.
‫Now here's the syntax.
‫It takes a trace channel.
‫Remember, we need to specify a trace channel and we're going to use visibility.
‫Now we have two additional input parameters.
‫The first is a bool called B trace complex.
‫We'll talk about what that means in a second.
‫And the third input parameter is an F hit result.
‫Now I'm going to click on F hit result just to see this type here in the documentation.
‫And if I scroll down, we'll see some of the variables.
‫One of them is called actor and it's description says Actor Hit by the Trace.
‫We also have this B blocking hit, which says indicates if this hit was a result of a blocking collision.
‫Now, among the other variables, we have things like impact point.
‫This is the location in space where we actually hit something.
‫So why don't we go ahead and attempt to call this function?
‫We first want our player, controller and thanks to what we did here and begin play, we have player,
‫controller, ref.
‫Now the first thing we should do is check to see if player controller ref is valid.
‫We can always pass a pointer into an if statement.
‫It'll return true if the pointer itself is not a null pointer.
‫If it is a null pointer, it'll return false in an if statement and we'll never reach the inside of
‫the if statement.
‫It's always a good idea to check our pointers and make sure they're not null before we use them.
‫Now we're going to get our player, controller ref and we're going to use the arrow operator to call
‫the function, get hit result under cursor.
‫Now we can see with the pop up that we have three input parameters.
‫The first is the Trace Channel.
‫We're going to use EA Collision Channel and if we type two colons, we get a dropdown that shows us
‫all of the different enum constants in the EA Collision Channel enum.
‫We want to use visibility, so we're going to type XY visibility to specify that we're using the visibility
‫channel.
‫Now the next parameter is called B Trace Complex and we're going to pass false into this.
‫Now we'll discuss in a few minutes what this means.
‫But for now we're going to use false.
‫Now for the third parameter, we need a hit result.
‫This is a struct of type F hit result.
‫Now, if you hover over this, you'll see that F hit result is being passed in as a reference as indicated
‫by the reference operator that looks like an ampersand.
‫Now, usually when you pass something in as a reference, it's a cost reference, meaning the function
‫won't be able to change it.
‫But here we're passing in an F hit result as a non const reference.
‫This is generally a hint that the function is designed to change this input parameter directly.
‫What get hit result under cursor is going to do is fill in those variables in the hit result with information
‫about the hit result.
‫This means we need to pass one of these f hit results in.
‫We're going to create a local variable here in the if check of type F hit result.
‫And we can call this hit result and we can simply pass this N as the third input parameter.
‫Now, after we've called this function, then this hit result will be filled in with data about this
‫line trace.
‫For example, we can access hit result dot actor to get the actor that was hit or dot impact point to
‫get the point in space where we had the hit event.
‫So the hit result is what we will use to get information about the line trace.
‫Now often it's nice to be able to see the result of a line trace.
‫We can easily visualize the result of a line trace by drawing a debug sphere.
‫Debug spheres are simple shapes that we draw in space, and they're great for showing a location and
‫we use these when debugging.
‫We don't actually use debug spheres in a shift game.
‫So let's see how we can draw one of these debug spheres.
‫Now here's the documentation for a function called draw debug sphere.
‫It exists in draw debug helpers.
‫So we can copy this header and include it wherever we like to call draw debug sphere.
‫Now look at all the input parameters.
‫First, it takes a world this way it knows which world to draw the sphere in.
‫It takes an F vector for the center of the sphere as well as a float for the radius.
‫It takes an N 32 for the number of segments for that sphere.
‫The more segments, the more round the sphere it takes an F color.
‫This way it knows which color to draw this sphere in.
‫It wants to know if you want persistent lines.
‫In other words, should the lines disappear immediately or should they persist?
‫If they do persist, it wants to know the lifetime of the sphere.
‫When should it stop drawing the sphere?
‫If you don't draw persistent lines, say you'd like to draw it for a single frame, then you would pass
‫negative one in as the lifetime.
‫Now the last two parameters are optional, so we'll keep this simple by only discussing the first seven
‫parameters.
‫Let's see how this works.
‫I'm going to draw a debug sphere now up at the top, I'm going to include draw debug helpers.
‫That's where this draw debug sphere function is declared.
‫Now let's go down to begin play and just simply draw a debug sphere to see how this works.
‫So I'm going to call draw debug sphere and the.
‫First input parameter is a new world.
‫We can get our world at any time by calling Get World, Get World Returns a new world pointer to our
‫current world.
‫So that will satisfy the first input.
‫Next, we need an f vector for the center of the sphere.
‫Now we're calling this and begin play so I can simply call get actor location and this will get the
‫location of our tank pond.
‫Since we're in the tank class.
‫Now I'm going to raise the sphere up by a bit.
‫So I'm going to add an F vector with zero dot F for the x zero dot F for the Y and say 200 F for the
‫Z.
‫Now I'm going to place these input parameters each on their own line.
‫So it's clear what we're passing in for each input.
‫The second input is getting this expression, which is the actor location, plus a vector pointing upward
‫with a length of 200.
‫Adding these two vectors together will give me the location of the tank raised up in the Z axis by 200
‫units.
‫Now the next input parameter, it's going to be the radius of the sphere.
‫I'm going to choose 100 F just so we can see what a debug sphere with a radius of 100 looks like.
‫Next is the number of segments.
‫I'm going to choose 12.
‫We'll see what that looks like.
‫Now for an F color, there exists an F color class and it has lots of colors built in such as red.
‫Now for the boolean called B persistent lines, I'm going to choose true.
‫And for the next input parameter we have the lifetime notice.
‫It has a default value of negative one.
‫That means by default it'll draw the debug sphere for a single frame.
‫But I'm going to pass in 30 F so that we get the sphere for 30 seconds and I can omit the last two parameters.
‫So here's our function call to draw debug sphere.
‫Let's compile this and see what it looks like.
‫Okay, so I'm back in the editor.
‫I'm going to open a second window so we can see this in full screen.
‫I can go to window view ports and select Viewport two and now I see this second window.
‫It may not be full screen when it opens up, but you can always maximize it.
‫Now from here I can play the game with alt p.
‫Now check this out.
‫Here's our debug sphere.
‫Notice it's not perfectly round.
‫We chose 12 for the number of segments.
‫The more segments you choose, the more lines it takes to draw the sphere.
‫Now, this is a sphere with a radius of 100.
‫It's pretty big, and the center of the sphere is at the location of the tank, plus 200 units up in
‫the air.
‫So this is how we can draw debug spheres.
‫So your challenge is to draw a debug sphere using the trace result under our cursor.
‫So draw a debug sphere in our new if statement where we're checking if player controller ref is not
‫null.
‫Now using our hit result, get the impact point from the hit result and use that as the Center for the
‫Sphere.
‫Now for the persistent lines input parameter use false and for the duration use negative one.
‫And this will result in drawing the sphere for a single frame, which is okay because we're calling
‫this every frame inside the tic function.
‫So pause the video and draw the debug sphere in the tick function.
‫Okay.
‫So I'm back here in Tank.
‫Now I have this draw debug sphere function call here and begin play so I can go ahead and copy that
‫and just remove it from begin play and we're going to go back up into tick here inside of our if statement
‫and I'm just going to paste it here and we're going to change some of the input parameters.
‫For one, we're changing the location for the center of the sphere.
‫We're going to use the hit result.
‫So I'm going to say hit result dot impact point.
‫Now for the radius, I'd like to make this a bit smaller.
‫Let's make it about 25.
‫That's okay.
‫If you didn't do that, I'm just doing this.
‫So the sphere is not so big.
‫Now, the second to last parameter we're passing in is for persistent lines.
‫I'm going to pass in false and for the duration instead of 30 seconds, I'm going to use negative one
‫point F.
‫That way we'll get a sphere for a single frame, which is okay, again, we're calling this in the tick
‫function, so we'll be calling this every frame.
‫Let's go ahead and compile this.
‫Now, back in the editor.
‫If I hit play now, check this out.
‫I have a debug sphere and it's being drawn at the impact point for the line trace under the cursor.
‫Now we can move this up the walls and on other objects and the trace is hitting these objects because
‫they're set to block the visibility channel.
‫Pretty awesome right now.
‫I promised we would discuss tracing complex versus tracing simple.
‫I'm going to show you something while we're playing the game.
‫Let's click in the viewport so that we have control over our palm.
‫Now hit the tilde key and type the console command show collision.
‫Now it may not be so easy to see on my screen, but you can definitely see it on your screen.
‫Notice the collision for our pawns.
‫Not only can we see the capsule, but we can see this collision volume around our tank and turret meshes.
‫This is simple collision.
‫Let me just show you real quick where we can see the simple collision.
‫I'm going to go into assets and meshes and if I double click on, say, tank base here, we're looking
‫at the complex collision.
‫If I click on this show icon here at the top and select complex collision, I can see all of the polygons
‫in the complex collision and there are a lot of them.
‫If I click the show icon again and this time check the checkbox next to Simple Collision, notice there's
‫another collision volume.
‫This is called a collision hull and it has a great deal less geometry.
‫There is a smaller number of polygons with this collision volume.
‫This is what the physics engine uses to detect for overlap in hit events.
‫If it were using the complex collision, it would require a great deal more computations.
‫This is why we have simple collision volumes, so it's much better for performance whenever doing a
‫line trace if we trace for simple collision instead of complex collision.
‫So now we've gotten the hit result under the cursor.
‫It took some work to get there, but now we have it and we've proved it by showing this location with
‫a debug sphere.
‫This is a nice way to confirm that our trace hit is working.
‫So now that we know it's working, we can use that location to rotate the turret on our tank.
‫And we'll do that in the next video.
‫I'll see you soon.