Game advanced level control of gun
Hello My name is Lee Yong Woo
We will learn about the control of gun in this chapter
We will learn about how to pickup, drop and shoot guns as learning contents
In each contents, we will deal with how to use
Enhanced Input which is added to unreal engine 5
First, in pickup guns, learn how to extract actors you want to find as per range search
And add it to mesh component of the character
Next, in drop guns, process logic to detach guns
Which is attached to mesh component
And last, in shooting guns, how to calculate
The point of view the player views via camera
And process collision using LineTrace
Pickup and drop guns
We have to get assets we need for picking up
So among the assets distributed
There would be this asset called PistolMesh
Unzip it, then there is PistolMesh folder
Bring this PistolMesh folder to NetTPS folder
Under the content folder by drag and drop
Drag it and drop like this
Now then, on the unreal engine editor
There is a popup window asking whether you would import it or not
Press import
And press import all
Now close the Message Log window
Then, under the NetTPS folder
You can see there is PistolMesh folder
Let's work this material into the form we need
First, in the PistolMesh folder we just brought
There is static mesh as well as material
And textures
There are textures we are going to use
We will make material by using these textures
Come to here and remove
This one called Param
Press delete to remove it
And then press ctrl + space bar to open content drawe
Under the NetTPS, under the PistolMesh, there is Textures folder
Let's bring what we need from here
First of all, take normal map
and connect to Normal socket
Next, there is one called T_Pistol_AORM
Grab this and drag and drop like this
It was AORM
This R channel goes into AO
It says Ambient Occlusion
AO stands for Ambient Occlusion
So put R channel into AO socket
Into Ambient Occlusion
Remain is RM, so connect G to Roughness
And connect B channel to Metallic like this
Then you can preview on the viewport window
Next, you can see T_Pistol_D here
Instead of just using it
There is masks texture next to it
We will blend it with this
Before we put it in Base Color
Therefore, take T_Pistol_Masks and add it
Then while pressing M
If you click empty space on graph
Multiply node will be added
Press M on keyboard to do it
Click while pressing M to add it
If you find it hard to do, then there is a palette on right side
Search multiply on the palette
There is Multiply node of Math
You also can drag and drop this
Now if you see this Texture Sample
Here is diffuse map image
Take this and put it in A socket of Multiply
Then the output
Goes into Base Color like this
Then now, as you see, they are mixed
Now let me blend this image
With blue background from masks into it
I'm going to add a Lerp node here
Press L on keyboard to do it
Click empty space of graph while pressing L
Click while pressing L to add Lerp node
Then put R channel into A
And G channel into B
B channel into Alpha socket
The output of Lerp
Goes into B of Multiply
Then you can preview on the viewport window like this
Now the whole graph is formed like this
Save and close this material
Next, to allow player to grab guns
We will add a component here
Come to Visual Studio Code
And move to the header file
With the name of NetTPSCharacter
Since all the components are added here on top
So I will paste here
Copy and paste UPROPERTY
Now the component we are trying to add here is
The one where guns will be added as child
Therefore make this component as SceneComponent
Declare class USceneComponent
With the name of gunComp
Then move to the constructor on NetTPSCharacter.cpp
And move down to the bottom of it
Type gunComp = CreateDefaultSubobject
Put USceneComponent into angle brackets
and GunComp as text into parentheses
Now execute SetupAttachment after gunComp
and GetMesh as parent component
Then mesh component will be the parent component of gunComp
And put in the name of socket here
Let's say GunPosition as text to be identified easily
Like this
Then this gunComp will be attached
To the GunPosition socket of mesh
Now build it once
Once it's done, go to the unreal engine and take a look
We can see Gun Comp under the Mesh component
Usually, if you don't see it, then
Please restart the unreal engine
As you can see, Gun Comp is attached like this
But in your case, when you started unreal engine
This Gun Comp could be on the floor like this
Since we didn't make a socket called Gun Position yet
It can't be attached to hands
It's normal to be attached to the floor
So Gun Comp needs to be on the hands to make
Guns are able to be attached to like this
Let's add a socket
So Gun Comp can be attached to that socket
Then where should we bring this socket
Select this Mesh component then on the right bottom of the editor
There is a mesh that this skeletal mesh component is using
You can see Skeletal Mesh Asset
There is preview image of skeletal mesh that is used
Double click this one
Good, you see
There is Skeleton Tree on the right
What we want to use in this Skeleton Tree
I will attach it to the right hand
So there is hand_l and there would be hand_r
If you keep goes down there is hand_r
Right click on hand_r
and click Add Socket
Then you will see hand_rSocket
Let's rename it
Since we said Gun Position on the code
So name this one as same
Alright
Then save it
and close the window
If you select Gun Comp
You can see it is attached to hand
Right? It is attached to hand like this
Now since we made gunComp
Attached to socket
Called GunPosition on the code
You can see it is well attached
Then attach gun to Gun Comp
to adjust the position
To check if it is well attached
There is SM_Pistol in PistolMesh
Attach it to the Gun Comp as child like this
Then it is attached to here
We don't edit this SM_Pistol directly
To adjust the position
The parent component above it, the scene component
We have to adjust it's position
So the pistol below
Needs to be set 0, 0, 0 under the Transform
Just keep it as you attached
So let's adjust the position of Gun Comp directly
It is hard to work because of the animation
Select Mesh component
There is Animation tab on the right side
If you open Advanced tab
You can see there's Pause Anims
Check this Pause Anims
Then you can see the animation attached to
Mesh component, the skeleton mesh, is paused
Now it'd be easier for us to work
Then let's adjust the position of Gun Comp
Let me rotate it first
Rotate a bit like this
Right? Then move a bit forward
I'm not adjusting SM_Pistol
As you can see, select the Gun Comp
Select it like this and adjust
Now then adjust the position
Adjust the position of hands
Like this
And it is tilted to one side a bit
It looks okay but
Let me tilt it little bit like this
Tilted like this
Then player is holding pistol like this
Now let's code these values
There is information of transform on the right
Take both location and
Rotation values from transform
And paste it
Right click here
Right click on location and select copy
and move to the code
Execute SetRelativeLocation on gunComp
and paste it as Fvector
Remove X,Y,Z parts and keep values only
Alright? Let's go get rotation values and set it
Right click on rotation and copy it as well
Then execute
SetRelativeRotation on gunComp and put values as FRotator
ctrl + v
Then you can paste it from clipboard in order
Set them like this
Then build it to process
So that this information can be applied on C++ class itself
Now then do not attach pistol direct to here
We are supposed to grab it by pressing key
So press delete on pistol
Press delete to remove SM_Pistol component
Then select Mesh component
Uncheck Pause Anims on the right
To get animation back
Compile it
Now make pistol we just created
Into blueprint
and place it via viewport on the world
By placing it on viewport
Make it available for us to grab the pistol
For making SM_Pistol into blueprint
Right click on Blueprints folder
Right click on space of Blueprints folder under NetTPS
Select Blueprint Class and choose Actor for parent
and name it BP_Pistol
Double click to open BP_Pistol
Add SM_Pistol as root component here
Press ctrl + space bar to open content drawer
Then SM_Pistol inside of PistolMesh
Drag and drop it
Added as component
Then select it again drag onto DefaultSceneRoot
To make it as root component
Now on the right side, if you're not holding the pistol
It supposed to be on the ground, right?
Therefore in order to apply it, on the right side
On Details window, there is Simulate Physics under the Physics tab
Check it to enable it
When player run into this pistol, it's not supposed to be
flown off or so
So we're going to make it not collide with player
There is Collision Presets below Collision tab
If you open this Collision Presets
You would see Pawn and everything is set as block
So let's change it to custom
Open dropdown menu on Collision Presets
and change it to custom
Change Visibility and Camera options
Under the Trace Responses to Ignore
Also set Pawn ignore
So both Pawn and player
Flying away when they collide with each other is
Not going to happen
Compile it and close BP_Pistol
And place it on world
Grab BP_Pistol and place it
Then it is stick to the ground
I'll put it little bit above so that it could be dropped when the game starts
Copy and place one more somewhat distance away
I'll make the number of players to 2 later
Let's place like this since it's multiplayer
Now if you press play then it would work normally
If it is not set correctly on World Settings
If your GameMode Override is not set correctly
Select BP_NetTPSGameMode here
Select BP_NetTPSGameMode as GameMode Override
On World Settings
Play again after setting then it would work normally
Let's create action to pickup pistol
For pickup action, if you go into Input, there is Actions
Pickup pistol is going to be just pressing and not pressing
Pickup button so it is similar to this Jump
If you double click it, as you can see, Value Type is set to Digital
Since it's bool, it will be pressing or not pressing
Therefore I will copy this Jump
and use it as it is
Press ctrl + D after select IA_Jump
to duplicate input action
And name it as IA_TakePistol
Then there is Input Mapping Context called IMC_Default
Under the Inputs folder
Double click to open it
After open it by double click it
Press add icon on Mappings
Then a dropdown will be added
Open it and select IA_TakePistol
Then for key binding, there is keyboard icon
Click it and press F on keyboard
Press F to set it
Now save it
Then let's add it on code
to make this input available
Go to Visual Studio
Go to the bottom of NetTPSCharacter.h file
If you scroll above, you will find that inputs already has been declared
In order to make it usable
So I'll just copy and use it
Press ctrl + C
Scroll down to the bottom, set as public
and paste what we just copied
Then the name of variable is not LookAction
But TakePistolAction
Then let's add function to process this input below
Choose either Move or Look and press ctrl + C
Move down and paste it
Name it as TakePistol
This value will be what we want: pressed, not pressed
Construct TakePistol
on cpp file
Added construction part like this
Then we have to bind it in order to map this input
onto input we actually set
Add that part to SetupPlayerInputComponent function
As you can see, we have jumping
Also have looking
Let me copy this looking
And add TakePistolAction instead of LookAction
Set it Started instead of Triggered
So that the moment key is pressed, input occurs
And add TakePistol function can be executed
In accordance with this input, not LookAction
Right?
Now we made the part when the input comes in
TakePistol function will be executed
Now then let's work on few things in order to grab pistol
How it would be processed
If player doesn't possess pistol
Then make it search and grab pistol within a certain range
Right?
Player does not supposed to grab another pistol while possess one
So it's only when they don't possess pistol
We placed two pistols in the world
We will make them grab the nearest pistol
According to this, we need some properties
Some information
Status whether possessing pistol or not
Right?
And they have to hold pistol
So which pistol do they possess
So that they can drop pistol later
We need to process drop after grab
Since we need to drop pistol, we need pistol they possess
Move this above like this
In order to make them grab pistol within certain range
We need pistol search range as well
So let's add these necessary properties first
Move to NetTPSCharacter.h file
Add properties right above the function
Make bool bHasPistol for whether they possess pistol or not
bHasPistol is false as initial state
Make it like this
Then we need pistol each player possess
Since the possessed pistol by each player needs to be pointer
Add UPROPERTY()
Declare ownedPistol as Aactor pointer
And set it as nullptr
And we need pistol search range as property
To make it available to be edited outside by planner
Add UPROPERTY as EditAnywhere
Set category as Gun
Add float distanceToGun
as 200
as 2 meters
Now we declared properties we need
Come back to cpp and construct this
Let's construct what needs to be done
When players don't possess pistol
Then will it work when they are holding pistol
No, it won't
Nothing works while possessing pistol
They're not supposed to grab another
So if bHasPistol is true then player is holding pistol
So just return in order to process nothing
This is what we implemented first
Now write down below what we are going to process next
What we want to process here is
Examine all pistols in the world and grab the nearest one
This is it, right?
So we need to bring all pistols in the world
Need to bring all of them to examine
But keep searching and bring pistols
Would not be good
For performance, use cache method
All pistols in the world needs to be examined
To find pistols among the actors when spawn first
Let's find pistols and assign them to variable
Move to NetTPSCharacter.h file
And remember pistols placed in the world
Add UPROPERTY and assign pistols to TArray
As the type of AActor pointer
Name it pistolActors
Then where they will be found
Find them at BeginPlay
Since this is the function which is called when starts
So search pistols at the bottom of this
Find pistols
and assign them to pistolActors
Assign all actors
to here and bring first
TArray for AActor, allActors
Since we have to find pistol actors
Among all actors in the world, so I made it like this
There is GetAllActorsOfClass function in UGameplayStatics
We are going to search actors at World
Put StaticClass
and put allActors where all found values
will be assigned to
Use for-statement and find Actors named pistol
and assign it to PistolActors
Put auto tempPistol : allActors into parentheses
Then extract one by one from allActors through range search
and put it into tempPistol one by one
Then use if-statement and search name of tempPistol
Use GetName and Contains function to check
If it contains BP_Pistol
Name of the pistol contains BP_Pistol
If you check the names of BP_Pistol
They are BP_Pistol and BP_Pistol2
So the name changes everytime a pistol is added
Therefore if the name contains the word BP_Pistol
Then that is pistol
Add tempPistol
to pistolActors
We don't have UGameplayStatics here so it's underlined with red
So let me add a header above
Include GameplayStatics.h which is under the Kismet
at the top in order to add it
Right?
Then move back to TakePistol function
Move back to TakePistol function
Let's write a code to examine
all pistols in the world and grab the nearest one
Use for-statement, we have pistols that we memorized before
Write auto pistolActor
from pistolActors
Extract on by one and assign them to pistolActor
and process
Before that, if the pistol has possessed by the other player
The other player is already holding the pistol
Then it cannot be taken away, right?
If the pistol has an owner, don't examine
Let's add this logic
Use if-statement, pistolActor It's actor not actors
Call GetOwner to examine
Does it have an owner?
which means it's not 'nullptr'
Then it means it has an owner, so don't examine it
Make it continue
Alright, then if the pistol has passed this,
Calculate the distance from the pistol and if it is within range, grab it
Let's calculate the distance from the pistol first
Declare float distance
There is Dist function in FVector
Put my current location, which is the actor's location
and the location information of pistolActor
Get both location to get the distance
Use one more if-statement
If the distance is within the range, we will take the pistol
If the distance is out of the range, what should we do?
Do we have to keep examining it? No
So if it is out of the range, process not to examine it
If the distance is out of the range, it has larger value
If it is larger than distanceToGun, the range we can check
No pistol is in the range, so continue
Process not to examine the pistol
Now the player grabbed the pistol
Then we need to register the pistol as an owned one
So write ownedPistol
Assign pistolActor as the pistol owned by the player
Then assign the player as the owner of the pistol
It means that
If you call SetOwner function
from ownedPistol and write like this
Then 'this' is assigned to owner
The NetTPS character becomes the owner of the pistol
Why is this so important?
We examine whether the pistol has the owner or not up here
So if the SetOwner function was called
Then it has an owner already
So the logic that does not examine will be activated
So come back down, we set 'this' as the owner of the pistol
Now the player is holding the pistol
So we should change it to having pistol status
Set bHasPistol to true
Now that the player is holding the pistol, put break
Alright?
If the player finds a pistol within the range and if it doesn't have an owner
Then the player grabs the pistol and registers him/herself as the owner
We finished this part in TakePistol function
Which means the owner has been registered
Now we have to attach this pistol to the component
So move to NetTPSCharacter.h file
and add a function under TakePistol
which attaches the pistol as component
Put 'void', we will name it AttachPistol
Put parameter as 'const AActor pointer pistolActor' and implement AttachPistol
Then this implementation part is added at NetTPSCharacter.cpp
Declare auto meshComp and call
GetComponentByClass from pistolActor
BP_Pistol is UStaticMesh
So specify it as UStaticMeshComponent
Then you can get static mesh component that contains SM_Pistol
Now which one should we attach to this as parent component
Use AttachToComponent
Attach Gun Comp
Write FAttachmentTransformRules as an attachment rule
SnapToTargetNotIncludingScale
to not include the size
Right?
The moment we grab the pistol, physics should not activate
So put SetSimulatePhysics of meshComp
to false so that the physics wouldn't work
And this AttachPistol function's work is
attaching this pistol to player's hands
Now that we found it, when TakePistol was called
We found even the owner
So attaching it to hands should be done at the bottom
So call AttachPistol with pistolActor that we have
as parameter
Now build it
Play it and you can see this 'grabbing the pistol' animation
So go to Animations folder and select ABP_Manny
There would be Has Pistol on the right side of the Details window
Uncheck Has Pistol at Anim Preview Editor
Then click apply and compile Then go to BP_ThirdPersonCharacter
There will be searching function on Details window
Select Class Defaults
and search input on Details window
We didn't register anything on Take Pistol Action
So open dropdown menu and select IA_TakePistol
to apply input and the asset
Compile, go back and play
As you can see, the pistol is attached to the hand
There is no animation working
but you can see that the pistol is attached
Then, we should apply animation
There is NetPlayerAnimInstance.cpp at Visual Studio
At the bottom of NativeUpdateAnimation,
Update bHasPistol with the value of
bHasPistol that we added to the player
Build again and go back to unreal engine
Play again and go grab the pistol
If you press F, the character grabs the pistol
That's it for the pistol grabbing animation
Now, we will work on pistol releasing
We need to assign input asset
just like pistol grabbing
So move to NetTPSCharacter.h file on Visual Studio
and add input same as pistol grabbing
There is TakePistolAction above
Take it and paste it as public at the bottom
and change the name to releaseAction
For pistol releasing function, copy TakePistol above
and paste it as processing pistol releasing function
and the name is ReleasePistol instead of TakePistol
ReleasePistol
Then add implementation
The implementation part is added to NetTPSCharacter.cpp
Go to the bottom of SetupPlayerInputComponent
You see this TakePistol part
Press ctrl + D to copy
Change from takePistolAction to releaseAction
Put releaseAction
and put ReleasePistol as a binding function
We binded both input of releaseAction and ReleasePistol
Then go to ReleasePistol
and add the implementation part
It's same as TakePistol
We have to release the pistol that we are holding now
So what if we are not holding a pistol?
Should we process this ReleasePistol input?
We shouldn't
Should we process the input if we are holding the pistol?
No, we shouldn't
So if we are holding the pistol
Then we process nothing
So use if-statement
If it's not bHasPistol
that is if we are not holding the pistol,
return and process nothing
Then, if we are holding the pistol
We should process about not holding the pistol
So use if-statement and we made ownedPistol already
If ownedPistol is not nullptr,
there would be some value in it
Let's put it like this
Then, we have to set it as not owned
bHasPistol let us know that it doesn't have a pistol anymore
and for ownedPistol, SetOwner
I'll put nullptr
So it's saying that it doesn't possess anything
And this part which has value in it
Make it nullptr so that it doesn't have anything
Then this pistol still is attached to my hand
So let's make a function to implement
releasing the pistol from my hands
Move to NetTPSCharacter.h file
and make a function to detach the pistol from the component
Let's say void DetachPistol
Put const AActor pointer
pistolActor as parameter
Now create the implementation part
Move to NetTPSCharacter.cpp
and write pistol detaching things here
It's also same as AttachPistol
A component is supposed to be detached
Get auto meshComp
This is a pistol and I will get
StaticMeshComponent from BP_Pistol
So call getComponentByClass from pistolActor
to get UStaticMeshComponent
and MeshComponent has Physics
Call SetSimulatePhysics
The pistol needs to be dropped to the ground
So set it true
Then to able to detach the gun component
call DetachComponent
No, DetachFromComponent
Put this function
There is FDetachmentRules
And write KeepRelativeTransform
Then DetachPistol, a function that detaches the pistol
is being implemented, right above this
There is ReleasePistol
When we make it not owned, even before handling the nullptr
We have to detach ownedPistol
So we detach the pistol here
Detaching the pistol
Call DetachPistol and put ownedPistol
Then the pistol will be detached from player's hands
Now, build it
Go to unreal engine, then go to Actions in the Input folder
Press ctrl + D to duplicate IA_TakePistol
Name it IA_ReleasePistol this time
It's IA_ReleasePistol
Then move to Input folder
and open IMC_Default
Click plus icon on Mappings
to add IA_ReleasePistol
Set Z with a key
Save it
and then move to BP_ThirdPersonCharacter
There is Release Actions under the Input tab
Assign IA_ReleasePistol like this
Compile it and go back and grab the pistol
Then press Z
Then the pistol is dropped, grab again and press Z
That's it for pistol releasing
Pistol shooting
Let's continue with the pistol shooting
Since shooting needs input as well
Move to NetTPSCharacter.h file
and add relevant content
Let's take the input from public
to action and releasing input process function
and paste it
Change releaseAction to fireAction
Also, change ReleasePistol to Fire
Put this implementation to cpp like this
Bind fire input with processing function as well
So put fireAction
In SetupPlayerInputComponent,
Put Fire instead of ReleasePistol
Add the implementation part to this function
First, this has to be processed while holding the pistol
So if we are not holding the pistol, don't process
If bHasPistol is false
Then we are not holding the pistol so return and don't process
Let's implement pistol shooting below this
with LineTrace that Unreal Engine provides
FHitResult is the type to save the result of collision
Make variable hitInfo, type of FHitResult
LineTrace connects two dots to make a line, right?
Because we are trying to get the result of collision of lines,
We need two dots
startPos, type of FVector
This will be on camera, towards where camera is facing at
So execute GetComponentLocation from FollowCamera,
like this
Now, the camera is attached
The camera is attached to the player
From the location of the camera towards where the camera is facing
We'll shoot right in the center
endPos, type of FVector
The direction camera is facing from StartPos
Execute GetForwardVector where FollowCamera is facing
We'll shoot just 100 meters
So write down 10000 like this
Since the pistol mustn't shoot the shooter itself,
there is FCollisionQueryParams in the condition of collision
Let's use AddIgnoreActor to register itself through params
so that I can't shoot myself
Now let's add some part that we actually shoot, which is LineTrace
To detect whether it is hit by LineTrace or not,
add variable bHit, type of bool
Execute GetWorld and LineTraceSingleByChannel
Put hitInfo where collision information will be saved
Put two dots, startPos and endPos
Put this into trace channel input
to process everything that can be seen into collision
And finally params
not to shoot myself
And if bHit is true, then let's process
so that we can mark particles where it is hit
Then declare marking particles as member
Let's write below Fire function on NetTPSCharacter.h
Let's add shot particle
Add UPROPERTY with EditDefaultOnly
Put category as Gun
Then UParticleSystem type class
with the name of gunEffect
Right? Then we just play this gunEffect
Go back to cpp
To mark shot particle, we can use SpawnEmitterAtLocation
from UGameplayStatics
Put GetWorld so that we can put the particle in the right place
gunEffect and location from hitInfo
We can see the spot shot by the bullet
Put default value of FRotator function
Write down true then build it
Now, go back to unreal engine, BP_ThirdPersonCharacter
It's already set to Class Defaults
We have to assign input to Fire Action first
But let me add Gun Effect first
Type gun effect to get Gun Effect
Click dropdown to assign P_Explosion
Assign P_Explosion to make the hit spot stand out
like an explosion effect
Then let me add gun input here
Go to Actions and select IA_TakePistol as well
Press ctrl + D to duplicate
Put IA_Fire
IA_Fire
Go to Inputs then IMC_Defaults
Add another mapping
which is IA_Fire this time
Click keybord icon and register left click
Click here to bind left mouse button
Save it and go to BP_ThirdPersonCharacter
Search input
Assign IA_Fire to Fire Action
Alright?
I think there is something wrong with the codes
In Fire function, it says startPos '='
We have to change it to '+'
so that it can make arrow from this location to this direction
Right? There was a typo
Change it to '+' and build it again
Alright, go back and play to execute
You can see it's working well
But the animation is not working
So this time let's add an animation
so that it works when you shoot
Go to Animations folder and search fire
We got three results, and among these
There is MM_Pistol_Fire, right?
Click right side of the mouse
Hover cursor on Create
Select Create AnimMontage
Make it to montage and play it
I'll just use the name created automatically
Double click to open the montage file
Let's add slots
There will be an anim slot window on the Window menu
Anim Slot Manager
It sticks to the bottom right corner
Then, there is an add slot button
Click it and type FireSlot
as the New Slot Name
Then we get FireSlot
And then on the left side, the default slot is selected
Click slot button and go to Slot name then you can find FireSlot
it's second one from bottom and select it
Then this montage is processed to be able to play on Fire Slot
it's now moving but close and reopen it
Then you can see it working normally
Let's edit the animation little bit
You see, there is ABP_Manny
Double click to open it
I will edit this Main States part
Bring Main States to this place
Make cache from this and use it
So if you type cache you can see New Save cached pose at the bottom
Change its name to MainCache
The top should be shooting and the bottom should be running
These two needs to be mixed
So add Layered blend per bone node here
Add Layered blend per bone node like this
Basically for MainCache to be able to be put into Base Pose
Click on the right side of the mouse
and search main cache then you'll see Use cached pose MainCache
Select it and connect to Base Pose
Then for Blend Poses 0
Value from montage if it exists
Otherwise, take the value of MainCache itself
Select MainCache and press ctrl + C and paste it
Here, we need our fire montage
So if you search default slot, you'll find this
Add this node in Montage
So connect MainCache to Default Slot
And the thing we want to use is Fire Slot
Select Default Slot and open Slot Name on the right side
Select Fire Slot, second one from the bottom
and put it like this to look organized
There is one more default slot from the beginning
Press ctrl + X to cut
and paste it here
Connect them like this
Save the output as cache again
The output from here
There is New Save cached pose, select it
And just name it as PistolCache
Right? Shooting for upper body and running for lower body
These two has to be mixed
Select Layered blend per bone node and go to the right side
There is index under Layer Setup
Click plus icon
Then one more of it is added
Then name it as spine_03
If you go to the skeleton
You can see that the middle one is called spine_03
We took the name of bone and used it as it is
So write down spine_03 like this
Alright
Now, move to the right, the value that goes into Control Rig
will be changed like this
Execute PistolCache while holding the pistol
Otherwise, execute normal MainCache as it is
Let me add it here
Click right on here
and search blend poses by bool
and add this node
Blend Poses by bool
Connect this output to the source
In order to put PistolCache into True Pose
Select PistolCache and connect
And for False Pose, connect MainCache
to it
and this switching value needs to be in here
For this Active Value, My Anim Settings under the VARIABLES
If you open it, there would be Has Pistol
Drag and drop it to Active Value to connect
Then these two will be swithed in accordance with this
Compile it
In order to execute the shooting animation
Go to NetPlayerAnimInstance.h file on Visual Studio
Add details about the shooting animation at the bottom
Montage used for shooting
add UPROPERTY
Put EditDefaultOnly and the category as Anim
Declare class type of UAnimMontage
Write fireMontage
Then shooting animation
Animation play function
Add shooting animation play function
Add void PlayFireAnimation
Then add PlayFireAnimation implementation
on NetPlayerAnimInstance.cpp
First, the player needs to have a pistol
Pistol ownership, right?
And we need montage
If bHasPistol is true
and have fireMontage
Execute Montage_play
Put fireMontage, which is what we want to play
and make it twice faster
Then we need to call this PlayFireAnimation
from NetTpsCharacter
So go to the bottom of Fire
on NetTPSCharacter.cpp
Right below the if-statement,
We'll write the code for the animation play
Declare auto anim
Cast UNetPlayerAnimInstance
Execute GetAnimInstance from GetMesh
Then call PlayFireAnimation
from this anim like this
Add header for UNetPlayerAnimInstance
Include NetPlayerAnimInstance.h to add it
And then build it
Select Class Defaults
On the right side, we should assign Fire Montage
Select MM_Pistol_Fire_Montage
Click Compile
Now let's go and play
Grab the pistol and shoot
There is a problem when shooting horizontally
Let's edit this
Go to ABP_Manny, you'll see Layered blend per bone
On the right side,
There is an option called Mesh Space Rotation Blend
Check it and compile
Go back and play again
Let's shoot again, it works well
But shooting while running looks weird
This is because when the animations blend,
The switching speed gets too slow
So in order to edit this,
there is Fire Montage that we are using now
Go to Animations folder and search
Double click MM_Pistol_Fire_Montage
There is Blend Time option at Asset Details on the left side
There are Blend In and Out
Both of them are set to 0.25
Change them to 0.05
0.05 for Blend Out
Now save it and go back to play
Grab the pistol and shoot
As you can see, shooting while running works well now
But we can see that
no matter where you are aiming, both upward and downward
Rotation values are being reflected
So let's apply these values
Go to NetPlayerAnimInstance.h file on Visual Studio
Make it able to save the pitch
So add a variable that saves the value of rotation
Add UPROPERTY and EditAnywhere
and BlurprintReadWrite
Then put Category as MyAnimSettings
just as same as we did above
Declare float pitchAngles
No, just Angle
We'll move the place where this pitchAngle should be saved
to NetPlayerAnimInstance.cpp
and add to NativeUpdateAnimation function
Let's add it here
Let's process in order to reflect the rotation value
The value of pitchAngle, there is
GetBaseAnimRotation from minus player
Here
It's not Anim, it's Aim
GetBaseAimRotation, we can get the aiming rotation value
If we use it as it is, then it would be between 0 and 360 degrees
But we need it to be from minus to plus rotation value
So we won't use this, let's add .GetNormalized
Then it would give us values ranging from -180 to +180
Apply rotation value pitch to this value here
Pitch is a vertical value
We added minus because the value of rotation is reversed
There is Clamp from FMathf
Use it to trim pitchAngle
from -60 to +60 before using it
Then build again
in order to save this value,
Go to ABP_Manny
There is Blend Poses by bool
Before that, when the player has a pistol
make sure it could be rotated up and down
while the player is holding it
So move this part a bit to the side
Before the node using PistolCache
I'll make the value of pitch is applied
Let me cut this first
Disconnect the value to True Pose
and move PistolCache a bit to the side
Then click right on here
There is a node called Transform (Modify) Bone
There is a Transform (Modify) Bone
Add this node
In order to put the output into True Pose
Take it and put it in
Then a converting node called Component To Local is added automatically
Let's put PistolCache
into Component Pose
Then a node called Local To Component is added here
Since we are going to add the value of rotation
Click right on Rotation socket
and select Split Struct Pin
Then it's all separated
Now Roll to PitchAngle
I mean connect the value of PitchAngle to Roll
to the Rotation X like this
Then select Transform (Modify) Bone
On the right side, the bone we will apply is under the Skeletal Control
Select spine_03
Then we will use the value of rotation
Under the Rotation tab, it's set to Ignore
Change it to Add to Existing
Compile and save it
Come back to the main window
Click play
Everything is fine if we do nothing
When the player gets the pistol, the camera is rotating up and down
Press F8, we can see the upper body is rotated up
and down in accordance with my mouse rotation
That's it for pistol shooting
Let's put together what we learned in this chapter
Pistol grabbing and releasing Pistol grabbing Add gun assets to the project and create BP_Pistol blueprint Create input action for pistol grabbing and figure out the mapping factors
Implement TakePistol function in order to process pistol grabbing on NetTPSCharacter class and write algorithm to examine nearest guns and grab it
Use AttachToComponent function to attach the pistol to the player's hands
Pistol releasing Create input action to release pistol and implement mapping factor Use DetachFromComponent to detach from the component of the player actor
Pistol shooting Create input action to shoot guns and implement mapping factor Learn about LineTrace which is the way to examine objects collide by throwing invisible line in the form of a half line in shooting
Create montage animation asset of unreal engine and learn the way of playing it to control shooting animation
Learn how to use Transform (Modify) Bone node on the animation blueprint in order to implement upper body rotation in accordance with the mouse control of the player