Collaborative Project
As of the 11th of April, I’ve worked on implementing mouse control into the game.
This will be using the Player Controller to help detect mouse inputs throughout gameplay, for this I’ve managed to implement a crosshair and decal that will follow the player’s cursor in-game. The player will be able to use this input to help aim for when they’re able to turn and fire projectiles.
The PlayerController implements functionality for taking the input data from the player and translating that into actions, such as movement, using items, firing weapons, etc.
docs.unrealengine, 2022
Once creating a Player Controller class in the game, I set it as the default Player Controller within the Gamemode’s Blueprint so that once the game begins it will activate.
Within the constructor of our Player Controller, I’ve enabled showing the mouse cursor and then setting the Default Mouse Cursor to a Crosshair (See Figure 1).
Once we preview the game, you’ll notice that we now have a crosshair that follows our mouse’s position (See Figure 2).
Next, we’ll need to create the input functions within our Player Controller’s header file. Using a virtual void, we override SetUpInputComponent and then create some voids based on pressed and released inputs as we’ll be using mouse clicking (See Figure 3).
Within Project Settings under Input, I create a new action mapping labelled “Attack”. This will allow us to use Key Presses and Releases for our inputs (See Figure 4).
Once the Action Mapping is created, we go back into the CPP file of our Player Controller and add in the inputs and void functions (See Figure 5).
To test whether these inputs work, we also include debug messages that’ll appear once the inputs have been pressed (See Figure 6).
Before we actually enter any code, I tried to implement a special material that would act as a decal that appeared under the location of the cursor on any location in the world.
To make a decal from our material, we change its properties from within the details tab. Under Material Domain, we set it to a Deferred Decal – the blend mode is also set to emissive to help our material glow in the dark.
Using RadialGradientExponential, we set a circular gradient for our material by adding values to the radius and density of them (See Figure 7).
For this material, I wanted to create a ring shape. I achieved this was that I had two different Radial Gradients, with one containing a slightly smaller radius than the other determining the thickness of the ring. I think added both gradients into a Lerp, with the smaller ring taking the alpha.
Figure 8 shows what the material looks like once placed into the game world.
Next up we’ll need to implement our decal into the player character’s header file, as shown in Figure 9.
Included is also a FORCEINLINE, which will help return our cursor as a sub object for when we need to use it in our Player Controller.
Within the constructor of the Player Character’s CPP file, I create the decal and set the material of it to a reference of the material I just created before. I set the cursor’s decal size to something smaller as well – included is a Quaternion for setting the cursor’s relative location (See Figure 10).
A Quaternion can represent a rotation about an axis in a 3D space, this will allow our decal to rotate about multiple axis’s simultaneously. It can also help consume less memory.
Quaternions consume less memory and are faster to compute than matrices.
Harold Serrano, 2016
Now in our Player Character’s tick function we’ll set it so that we set the decal’s location to the player controller’s mouse.
Once casting to our Player Controller, we’ll use an FHitResult struct to help us place a hit result under our Player Controller’s cursor. Once we get a result, we then set our Decal’s location and world rotation to it (See Figure 11).
In-game, we can now see that our decal is following our cursor’s position every tick when we move it around (See Figure 12).
Now that there’s a decal that follows the location of our cursor, I’ll be using the FORCEINLINE subobject of our decal from the Player Character to use within the Player Controller’s Attack void.
Figure 13 show’s the function containing a debug message, one the player presses left click on any location within the game, it will set a pointer towards the Player Character and return GetCursorToWorld’s component location – for this to display within the debug message we also convert it to a string.
Once the attack key is pressed, our debug message will display the current location of the cursor. With this, we know that we’re able to pinpoint a certain location each time the left mouse button is pressed (See Figure 14).
Later on in development, I’m hoping to use this for player attacks and projectiles. The plan is to have the player always constantly facing and attacking towards the location of the cursor – this is how most traditional Top Down games handle controls for attacking.
Bibliography
Docs.unrealengine.com. 2022. PlayerController. [online] Available at: <https://docs.unrealengine.com/4.27/en-US/InteractiveExperiences/Framework/Controller/PlayerController/> [Accessed 23 April 2022].
Serrano, H., 2016. Developing a Math Engine in C++: Implementing Quaternions — Harold Serrano – Game Engine Developer. [online] Harold Serrano. Available at: https://www.haroldserrano.com/blog/developing-a-math-engine-in-c-implementing-quaternions [Accessed 23 April 2022].