‫Hello and welcome back.
‫Now we have movement for the --, but we're not rotating that top part of the --, which we're calling
‫the turret.
‫So we'd like to be able to do that using our mouse.
‫Now, take a look at what's going on here.
‫As I'm moving my mouse cursor around in the world, I'm getting this red sphere.
‫This is a debug sphere that I'm drawing in 3D space.
‫Now notice as I move up against a wall, that sphere moves against the surface of the wall.
‫So wherever my mouse cursor is moving, I'm getting this fear that corresponds to whatever object I'm
‫hitting based on my cursor location.
‫And this is going to be useful for us so we can have a location in space that we can rotate our turret
‫towards.
‫Now, in order to do this, there are some functions we need on the controller, so we have to access
‫those functions on the controller.
‫And in this video we're going to work on setting that up and we're also going to discuss how this is
‫going to involve a concept known as casting.
‫Now, the reason we want the controller is because there are functions on the controller that allow
‫us to get the hit result under the cursor.
‫Now we're talking about the mouse cursor.
‫So say this is our screen and here's our mouse cursor.
‫And the point at the tip of the cursor corresponds to a location on the screen.
‫Now if we move the cursor around, our goal is that the turret part of our tank, that top part of our
‫mesh is going to rotate so that it's facing the direction of that cursor.
‫Now if we move the cursor around, there's a function on the controller that we can use to get the location
‫corresponding to that cursor.
‫If we were to draw a line straight out from the camera towards the cursor and hit some object in the
‫world, we can get that location and use that location to set the rotation for the tank turret.
‫Let me show you what I mean.
‫Now, in order to get this hit location corresponding to our cursor, we need to use the controller.
‫Now, let's talk about the controller for a brief moment.
‫Let's say we have our pawn in the world.
‫A pawn will have a controller.
‫This is an invisible object that's associated with the pawn.
‫Now, for our pawn, our controller is going to have the type A player controller and at the beginning
‫of the game, the controller will possess the pawn.
‫This is why we can see from the point of view of the camera that belongs to our pawn tank.
‫Now we can access this controller.
‫Our tank class inherits a function called Get Controller.
‫It's inherited from the -- class.
‫So what we'd like to do is get a hold of that controller and store that in a variable so that we can
‫use it to access the function we need to get the hit result under the cursor.
‫So let's set ourselves up for that.
‫Now I'm here in the tank class and the place we need to access our controller is begin play.
‫If we do it in the constructor, that's too early and we may not have a valid controller just yet.
‫So we're going to need the begin play function here in the tank class.
‫Now we have it here in the base pong class and so far we're not really using begin play in the base
‫pong class.
‫So what I'd like to do is move it over to the tank class.
‫So I'm going to highlight begin play, including the comment and the protected section here and I'm
‫simply going to cut it.
‫And then back in tank stage, I'm going to paste it.
‫Let's add this protected section here just above the private section with begin play inside.
‫Now we've removed Begin Play from base pawn.
‫We no longer have it here, but we also need to remove it from base pond cpp.
‫Here it is.
‫We can go ahead and delete it here and now we have it declared here in Tank H, but we also need to
‫define it in tank CPP.
‫So I'm going to define the function just under setup player input component.
‫So it's going to be void begin play with no input parameters.
‫There's the function body and we also need a tank pre fixing the function name.
‫Now we know it's important to call super big in play.
‫So that way any functionality in the begin play function and any of the parent classes will be still
‫called.
‫So here we have begin play.
‫This is where we can get our controller and store it in a variable.
‫So let's go back to Tank H and create a variable.
‫Now this is going to be private and I'm going to stick it down here at the bottom of the private section
‫and it's going to be a player controller pointer type and we can call this player controller ref.
‫This will be our reference to the player controller.
‫Now we're not talking about a C++ reference.
‫This is still just a pointer, but we're going to use this to refer to the player controller.
‫So now we have a player controller ref variable of type A player controller and we're ready to store
‫the controller in this pointer.
‫So let's go back to Tank Dot CP here and begin play and attempt to do this.
‫So.
‫What I'm going to do is say player, controller, ref equals and I'm going to attempt to call get controller.
‫Now get controller, as I mentioned is on the -- class.
‫Lets right click and go to definition and notice that this function returns an A controller.
‫Now our variable is of type A player controller, not a controller.
‫So what we're attempting to do here is take the return value from get controller, which is of a controller
‫pointer type and we're trying to store it in an A player controller pointer.
‫Notice we see the red squiggly here.
‫It says a value of type.
‫A controller pointer cannot be assigned to an entity of type.
‫A player controller.
‫We're getting an error.
‫Let's take a look here at the documentation for a controller.
‫Take a look.
‫Here's a controller.
‫And it says inheritance, hierarchy.
‫And below a controller we see a a controller and a player controller.
‫This means a player controller is a child class of a controller.
‫Now, in C++, we cannot have a pointer of type.
‫A player controller store the value of the address of an A controller.
‫A controller is the parent type.
‫A player controller is the child type.
‫You cannot take an object of parent type and store it in a pointer of child type.
‫So how do we get around this?
‫So here's our problem.
‫The get controller function returns the address of an A controller.
‫Now, this is something we could store in an A controller pointer, but we can't store it in an A player
‫controller pointer.
‫The funny thing is, though, that the object returned by get controller is in fact a player controller.
‫So we have this address in the form of an A controller pointer and we know it's stores a player controller,
‫but if we have it in the form of an A controller, we cannot access the function that we need because
‫it exists on a player controller.
‫The function is called get hit result under cursor.
‫Now if we have a value of type A controller pointer and we attempt to get that function that exists
‫on a player controller, we will fail to do so.
‫We'll get a compilation error.
‫So since we know the object itself is a player controller, it's just stored in an A controller pointer.
‫How do we get around this problem?
‫The answer is we have to cast.
‫We know that a controller is the parent class and a player controller is the child class.
‫And we know that we cannot have an A controller stored in an A player controller pointer.
‫We know we can go the other way around and have an A controller pointer store, an object of a player
‫controller.
‫That's in fact what we're seeing when we call get controller, it returns an A controller pointer that
‫points to an A player controller.
‫So if we have a value of type A controller pointer, we can use a special function called a cast to
‫convert the type of the pointer to an A player controller pointer.
‫So casting changes the type of one pointer to another pointer type as long as the object itself is the
‫type that we're trying to cast to.
‫Now, if we attempted to cast to an invalid type, for example, we have an A controller pointer pointing
‫to a player controller object.
‫If we attempt to cast to say, a character, the cast function returns null and we say that we fail
‫the cast.
‫So the cast function looks like this.
‫It's a template just like create default sub object.
‫This template function will adapt to the type chosen and in this function, the type we pass in is the
‫type we're casting too.
‫So we pass that type.
‫We'd like to cast two inside the angle brackets and we pass the pointer that we'd like to cast into
‫the parentheses.
‫Here's an example.
‫Let's say we'd like to cast to a player controller and a pointer of type A controller type.
‫We pass the pointer into the parentheses and the type we're casting to in the angled brackets.
‫And what gets returned is a value of type A player controller pointer.
‫So here's the function call where we're passing the type in the angle brackets and the A controller
‫pointer value that we get returned from get controller can go in the parentheses.
‫So we need to cast this value that we're getting returned from get controller.
‫That's going to be your challenge.
‫So in Begin Play, use the get controller function and pass that value in to the cast function and cast
‫to a player controller.
‫And then you can store the result in our player controller ref pointer, which is of type A player controller
‫pointer.
‫Pause the video and perform the cast.
‫Okay.
‫So we've almost got all the work done here we just need to cast.
‫So what we're going to do is call the cast function, which has angle brackets as well as parentheses.
‫And what goes in the parentheses is the value that we'd like to cast.
‫Now get controller returns a pointer of Type A controller.
‫I'm going to move that right here into the parentheses.
‫And the type we're casting to is a player controller.
‫So again we're taking the value returned by get comptroller.
‫This returns an a comptroller pointer or an address.
‫Then we're using cast to cast it to an A player controller.
‫We know that the object returned by gate controller is an A player controller object stored in an A
‫controller pointer.
‫So after we've cast this, what gets returned is a pointer of type A player controller.
‫So we're storing that in player controller ref.
‫Now that we have access to the controller in the form of an A player controller pointer, we can access
‫the function we need to get the trace hit result under the cursor.
‫So in summary, we used get controller to gain access to the controller.
‫We also use the cast function to cast from the type A controller pointer to type A player controller
‫pointer.
‫Now we can access the function we need, which is get hit results under cursor which exists on the A
‫player controller class.
‫So we'll start using this function in the next video.
‫I'll see you soon.