Hello, my name is Lee Young hoon
In this session, we're going to implement shooting and sniper modes
In this chapter, we will add a grenade launcher and a sniper rifle to the character
We will learn how to implement the functions of each gun
We will also learn how to swap between guns based on user input
And implement a Crosshair using widgets
First, let's place the grenade launcher and sniper rifle
Placement of grenade launcher and sniper rifle
If the player is positioned like this
We will place two guns in front of the player like this
We will place Gun 1 and Gun 2 accordingly
Next, when Gun 1 is fired
This is a regular gun
We will implement the bullets to be fired in a straight line
And then for the Gun 2
Something invisible like a laser will shoot out
And there will be a visual effect VFX of explosion effect
I will demonstrate those elements here
To implement these, we'll also need to add input commands
We'll need input commands for selecting the guns
I'll use the number 1 and 2 on the keyboard for selection
And we'll need to be able to zoom in, right?
For the sniper rifle, it should have zoom functionality
And then for the actual shooting
These kinds of inputs must be made
So, the first things first
Let's place the guns first
Launch Unreal Engine to start off
I've prepared some files
These two files here
I'll create a folder named Models
And copy those assets into it
I'll create a folder named Models using Unreal Editor
And open the Content folder
I'll copy them over here
I've copied them like this
Then the program will ask you if you want to import them
Let's click import
If you click Import All button you will see that everything's been implemented well
Then, you can find SniperGun and FPWeapon here
Select these two
And move them to Models folder
Drag and drop and select Move Here option
And I'll move the SniperGun to Models by selecting Move Here
And in Models, if you take a look
SniperGun looks like this, but now that I think about it
We are missing Material, let's fill it up by sliding up
Here are two types, diffuse and normal color
Put the diffuse map into this one
And I'll insert the normal here
By doing so, you can see that the texture fits well
The gun is well made, you can see the colors are applied nicely like this
This is a gun that originally comes with the Unreal Engine as an example
We'll be using this one
The regular gun is set as a Skeletal Mesh
And for something like the SniperGun, it's set as a Static Mesh
So, we'll be implementing these
Let's move to the player's header file
Let's start off at the bottom
We want the Gun here, so I will write UPROPERTY
And EditAnywhere and have the class be as Skeletal Mesh
And then USkeletalMeshComponent
Here, let's have this as GunMesh
Copy them all up and make one for Static Mesh
Let's name it the SniperMesh
Let's proceed to implement this now, move to the constructor
And continue writing at the bottom
We already have what we want over here
Copy and paste to save time
This one was USkeletalMesh
I mean USkeletalMeshComponent not just Mesh
Write one up like this
And then the same goes with the sniper
Write this one with UStaticMeshComponent
Both Mesh are going to be attached to GetMesh
So GetMesh will be SetupAttachment
And then GetMesh
The same goes for this one as well
Since for these objects, we won't be using collision object
So, let's use SetCollisionProfileNAme
And add NoCollision
Also do the same for SniperMesh
After adding that, we have to
Connect the Meshes to assets
Up here, we've done this
We used FObjectFinder to handle these
We will use the same method for these ones
At the bottom, copy and paste and this one should be TempGunMesh
Make sure you name them right
This one still will be SkeletalMesh
Seems like this should be good
The actual implementation will be for this one, not that one
Write like this and will attach them for now
We'll come back to review the content here later
And I'll just copy them and for the SniperMesh
We will use StaticMesh instead of Skeletal
Let's change this Temp to Sniper as well
That's that and this one should be UStaticMesh
I'll change it like this and replace all the names
Load everything like this
Now let's find the path
Right here
Right click with your mouth
Just use Ctrl and C as a short cut
So you can use that to copy
Sniper goes to the bottom one, so paste it there
Let's do the same for the top one with GunMesh
GunMesh is right here, so copy it with Ctrl and C
Or you can just copy the Reference here
And come over here to add it there
And make sure to change
TempMesh to TempGunMesh
And turn off Unreal Engine to try compiling again
And then run it again
I'm going to adjust the size and position of GunMesh and SniperMesh slightly
Let's go to player and try adjusting
After locking this, make small size adjustment like by 0.125
And the position as well
Let's move it up a bit, and same for GunMesh as well
Alright, let's set it like this
Compile and run it
We can see it working well
In order to handle input
Let's add four inputs, concepts of selection
Zoom and shooting
If you look here, go to Input and select Input Action
Make IA_TPSChooseGun
Let's copy this and name it Choosesniper
Copy it
Name it Zoom and copy another to name it Fire
I created total of four inputs
They are all type bool
Let's register it here
Let's do it one by one
ChooseFire, it's my mistake, it's supposed to be ChooseGun
Should be just Fire
I'll set Fire input as left mouse button
And then add, ChooseGun and Sniper
I'll have ChooseGun as number 1, and 2 for Choose Sniper
Zoom should be right click button
We want right click press to process Zoom In
And releasing to process Zoom Out
Now let's switch the name, Zoom
Change ChooseZoom into Zoom
So, place it like here
Go to the main character and in the TPS player header
Register all those keys
Add one, two, three, four
So, here should have ChooseGun
Since it's Choose something
So, let's make it simple and name it just Gun and Sniper
And this one will be Zoom and Finally, Fire
So, we've added four
Now, we need to make a input function
With these, Gun and Sniper
This one is Woom in and Lout
Let's make two and put Fire
I'll register all these functions first and then proceed with the implementation
Let's go to the source file and register those functions
Copy Jump and with other new makes it five
Gun, Sniper, ZoomIn, ZoomOut, and Fire functions are available
Do the same thing
Press Alt to get a hold of this block here
Gun, Snipper, Zoom, these are both zoom
Zoom will be changed to Started and Completed
This should be arranged under Fire
The other actions trigger upon pressing,
And For, ZoomIn and lout will p
Implementing gun swapping and crosshair functionality
Now then, let's start by implementing gun swapping
So, now that these functions are implemented, we'll handle the processing here
Then, Remember which gun we are currently wielding
You'll need to remember which gun you're currently wielding
Like when you ZoomIn while firing
Then you'll need to branch at that point as well
When we have the sniper instead of the default gun
We'll need to fire bullets differently
We'll create a variable here to facilitate branching
Here, write bool
And bChooseGunSniperGun
Initially set it to false to indicate starting with the default gun
Now, let's go back and try one by one
When having Gun, it should be false
Copy it and make it true for sniper
And each time you select this
The gun should appear and disappear
When you initially select the Gun, it should appear like this
The regular gun is actually a grenade launcher
The grenade launcher will be visible, and then the sniper rifle won't be
This is how we want to handle it and do the opposite for this
To achieve the visibility toggle between the two components
We are already using it as components
We have GunMeshComponent
To make this visible, you have the SetVisibility function available
You can use this functionality
If you make it true, you'll be able to see it
And then use SetVisibility with false for SniperMesh too
Write it like this
Do the opposite in the bottom, this one to be false and that one to be true
Now wrap it up and compile it one more time
Let's try running it, try number 1,2,1,2
Input doesn't work now
The key assignment part probably hasn't been included here yet
If you look at class default
It's missing, we need to fill it up
In IA Gun, ChooseGun, ChooseSniper and Zoom and then fire
Fill all of them up
Now, press 1 and 2, you can see them swapping
It seems like we need to start in this state at the beginning
Let's handle that too
It will work if we call
OnIAGun at BeginPlay
So, we are going to call it
Go in the top and call in BeginPlay
When we call it, we need variables
Alright, so let's create an FInputActionValue and set it up
To make it appear as the default gun when initialized
That's why we did this
And when handling this, we'll also work on the UI
Structure like this
you'll see the default gun first, followed by the sniper rifle
Then, you have a UI named Crosshair designed like this
Then, there's a Sniperscope image that fills the screen
With a hole in the middle for aiming
Let me show you this
If you look at this model, SniperGun
This is Crosshair and the image I've talked about
I would like to make it an UI to control it
So, you want both UI elements to be invisible
when using the default gun and visible when using the sniper rifle
Let's say this is the Crosshair and this to be Sniper
If we were to name it like this
And if ZoomIn when using Sniper rifle
You can see the S and then the Sniper
And whem ,Zoomout, have the default Crosshair
This is how we handle it
And when holding a default gun, Both won't be visible
Let's handle that like that
The reason is that default gun shoots in front of the barrle
But for sniper, we shoot align to the camera's front view
You'll be aiming at the center of the screen
So, we'll display this UI only when using the sniper rifle
I should create the UI, then. Let's head to the Blueprint folder
Here, let's create two widget blueprints as User Interfaces
I'll name it WBP Crosshair.
Back in the old days without scopes
They used human hair to improvise shooting guns
That's where the term crosshair comes from
I'll duplicate this one, and name it WBP Sniper
Like this, we made two UIs and it needs to be filled up
Here, let's make canvas for now
And I will insert an image
0If you search here you'll find Crosshair it here
Add it like this
I want it as a sqaure
Center it with an anchor
And then 0.5 and about 200
200 might be a bit much, let's do 150
Let's put it here and then 0,0 should be fine
Let's change the color to red or something
Similar to give it this kind of look
Compile this, and then I'll try the sniper one next
Same way, canvas then, insert images
And I want to insert the images at their original sizes
Positioning in the center is the same
Centered it
And then place at 0.5, 0.5
Then you'll see Sniperscope here
You can put that in
It's really small but if you double click it
The real size is 3364X2342
I'll insert them as 3364 x 2343 pixels
I'll input it as 3364 by 2343 pixels here
So now compile it and save
Then, we've prepared who kinds of UI
Let's have the player run the UI and control it
Then it goes to the player's header
Now we have to prepare UPROPERTY EditAnywhere in the UI
Bring this TSubcalssOf
That is UserWidget attach it to class
And here, CrosshairUIFactory
And then make another
Do the same for the sniper
Here, SniperUIFactory
And then UUserWidget keep what we actually made
This one is used to create
And having actual thing
Control visibility
We also use UPROPERTY here
I won't place indicator here
And then write class UUserWidget
Write CrosshairUI
Make one more and name it SniperUI
We will have it BeginPlay initially as we enter
We will let it load there
Let's go to BeginPlay in the source file
Since we have to control the UI here
create and remember the widget in the upper part
Those will be Crosshair and Sniper
They will be creating and remembering two widgets
write CreateWidget
If you look here, there is OwningObject
Usually, insert World, write GetWorld
And next, insert Factory
And then add CrosshairUIFactory
Then you'll need to add the header to receive this
You'll need to add the header for "UserWidget" to achieve this
Like so
For you to take a look
Let's see if it goes into the upper part
Then they are all added
To create a UserWidget and handle showing and hiding it specifically
In order to change visibility
We need to register and use the UMG module
So, let's add this one, too
We are going to add a module, so go to Build.cs file
Add EnhancedInput
And then add UMG on the side here
You need to add a module in order to use it
Now let's go back
Now, place these in CrosshairUI
And make another just like we've been doing
This one will be placed in SniperUI and here SniperUIFactory
And with default gun, both UI will be made invisible
So, in here, we need to make it invisible
We will go here and handle it, OnIAGun I mean
We did these things to hide Grenade launcher
Let's handle it here together
CrosshairUI has Setvisibility here too
But here, the argument passed as a parameter is slightly different
We'll name it Hidden since we're going to hide it here
Duplicate another and name it Sniper
This one also will become hidden
I also want to hide this UI
And further down, there's something called Zoom
We have this Sniper as well here
Similarly, We need to add content related to the UI here as well
Therefore, we will do the same here
If you've selected Sniper, then instead of hiding the UI
We want only the Crosshair UI to be visible, like this
Then Crosshair will not be Hidden
But visible
And below here, when you zoom, it'll be different again
When ZoomOut, the crosshair is visible
On the other hand, when it's ZoomIn, we will be able to see sniper only
It will become like this and there will be changes here
This becomes Hidden and do the opposite
However, Zoom should only function when we're
holding the SniperGun
It shouldn't work like this when using a regular gun
So, here we'll use a conditional statement if bChooseSniperGun is true
If this one is false here, we will have it returned
Here as well, you can just do it the same way
And for Zoom, we need to adjust
If you look here, there's a camera
We gave our character a camera component
There is something called the Field Of View
It means what it means
People can typically see about 90 degrees with one eye
So, if you hold your finger to the side
You can still see the finger a little bit
So, generally, it's considered that one eye
Has a field of view of about 90 degrees
Therefore, It is said that with both eyes
We can see a total of approximately 180 degrees
So we use the value of 90 there
since this concerns field of view, a wider FOV means seeing things farther away
While a narrower FOV means seeing things closer
So, if you decrease this value, it zooms in
And if you increase it, it zooms out to see things farther away
So, I'll try to handle this using that information
Then ZoomIn should result in zooming in
Here, we've done this before
We have the camera CamComp, and it has the Field Of View parameter
Let's try value of 20
Try different values yourself and find
The one that works for you
ZoomOut means that your field of view goes back to normal
Since it's default put 90
Now, compile to see the result
I didn't fill up the UI, let's start again
I didn't fill Factory and caused some errors
Open up main character's blueprint class an scroll down
You should be able to find UI Crosshair
Crosshair, and then here, we'll insert Sniper like this
Compile, then run the program
If you press number 2, the gun swaps
mouse right click to zoom in and release to zoom out
However I don't see the UI
Now that I think about it, we just created the UI and didn't attached it to the screen
It exists but not visible
So, let's attach the UI to the screen
Write AddtoViewport in CrosshairUI for it to show up
Same goes for the SniperUI, write AddToViewport
Go back and compile
Run it and press number 2, we see that the UI shows up
Right click for zoom in
Release to zoom out
Now let's try and fire the weapon
Number 1 to fire, Number 2 to see the VFX
Over there with the boom effect
Implementing shotgun and sniper rifle functionalities
Let's work on the default gun first
We need bullets, let's create them
Right click to make blueprint class
Let's begin with C
Choose the actor and come over here
Name it BulletActor
Write BulletActor and then Create
We have our bullet
Let's make the blueprint first
Try BP BulletActor in the blueprint folder
We need to do some coding here
Go to Bullet Actor
We need collision object in the header
Since it will be a bullet, it needs a body
It can be something sphere shaped
And it needs to move
Now, we can use MovementComponent
There is a component for a projectile object
We will utilize that to control this
So, collision object
Appearance, then projectile object
Create these three and write UPROPERTY EditAnywhere
Since it's collision object, Class, let's do sphere shape
We can use USphereComponent
It will provide sphere body
Since it's collision object, let's say CollisionComp
And copy these
To make StaticMeshComponent for handling appearance
Write MeshComp here
Make another and this one is for the projectile object
Write Class and follow it with UProjectileMovementComponent
This is a component
Write MovementComp because this component will handle movement
Let's implement these in the constructor starting with the collision object
Write RootComponent and CreateDefaultSubobject here
Write USphereComponent and TEXT
Will write another one with the same name
This one then, should be SetRootComponent
We will add the header
You guys can do what I did
If you have this program, utilize that
Or I taught you how to find it
You can search it up on google
Therefore, we have the header here
You can copy and paste the whole thing
Anyway, find an easier way for yourselves to do this
We will use this root and MeshComp with copy and paste
Write MeshComponent down
This is a UStaticMeshComponent
Let's attach this one to the Root
SetRootComponent I mean not this
Use SetupAttachment and then RootComponent
And the let's make projectile
MovementComp is CreateDefaultSubobject
Write Movecomponent, no it should be Projectile
Write UProjectileMovementComponent here
You will also need the name like this
I will keep it exactly the same as the variable name
But this doesn't have SetupAttachment
If you look here, there's no SetupAttachment
This only got like UpdatedComponents
Because If you go up to ProjectileMovementComponent
This one inherited the MovementComponent
If you look, this one inherited the ActorComponent
Since they have't inherited SceneComponent
This one doesn't have Transform
That's why we cannot Attach them
This should be good to know also
Let's go back
Let's add header for this one too
Add it like so
And next, this is
Since MovementComponent cannot
Use Transform by itself
We have to have it depend on other components
If you don't designate UpdateComponent
It will utilize RootComponent
If one decides to leave RootComponent alone
And decides to use and fire collision object
with other components, We can use MeshComponent
Collision doesn't do anything and Mesh will shoot out byitself
So let's just set it to the root
It seems like that it's better to have the CollisionComponent itself shooting out
Let's match it like this
Since this is a projectile, there are several attributes
If we look at it here, we have something called InitialSpeed
Let's have the initial speed as 5000
And in the MovementComponent
There is something called MaxSpeed, speaks for itself
This one is initial speed and that one is the maximum speed
If one decides to have the speed gradually going up, you would set them as different values
But I want to set them at a constant speed
Therefore, MaxSpeed will have the same value of 5000
Also, I would like it to bounce
I would like it to bounce
So, we use bShouldBounce
Set it as true for allowing the projectile to bounce on the ground
Also, we can decide how bouncy it will be using Bounciness
The value should be from 0 to 1
Let's try 0.3
And I would like it to be block instead of overlap
I want the effect of the object to handle every other objects as blocks
To actually hit every objects
So that the projectile will bounce around like I want it to
Put CollisionComponent in SpheereComponent
We want SetCollisionProfile and write TEXT
This one here, I want it to become block with every other objects
So, designate BlockAll like this
This is already a configured name
if you go to Edit Project Settings and look under Collision
In the Preset section, we can find BlockAll
I used this exact name
There's something that's already been designated
And next, for Mesh, it should not collide
Let's turn off Mesh as collision object
Just like before, put SetCollisionProfile to Mesh and then TEXT
Set NoCollision
This name is also over there
If you look here, you can find NoCollision
I just used this name
Now, compile one more time
Then we should give it a shape
We can handle this as well
But this would be too big for a bullet, the diameter being 1m long
We should reduce the size
It's set to 32 here, but I'll reduce it to around 13
Let's insert an appearance
This one is 1m long
The collide object is really small but this one is big
Let's try reducing the size like this
Reduce the size about like this
0.25 works just fine
About 0.25 must be good enough
Compile it and switch the Material as well
Search for Basic Shape Material
After the bullet is fired
And as long as you don't turn off the app, it will exist forever
Let's shoot some first
If you look, it flies away
What we want is that we want them to disappear after some time
So, let's give it some amount of lifespan
If you look here, you can find Life Span
Set it as Default
Give the value for the Life Span
Should we designate it as C while we're at it?
Here, you can find SetLifeSpan
Three seconds? You can set the time here
In float, lifespan is entered like this, in seconds
So if you set the value as 3, it will disappear after 3 seconds
Let's say 3 seconds
So, compile it like this
Now, if I do left mouse click
We can actually have the bullet generated for firing
So the bullets do disappear after 3 seconds but it's hard to notice
Then let's go to the player and implement that
Start with UPROPERTY and EditAnywhere
TSubclassOf then class with AbulletActor
And then BulletFactory
So when fired, we can generate bullets
And place them
And while we are at it, let's do this too
When ShiperFun is fired, VFX will be activated as well
So, let's make that happen here
So let's use the same method with UPROPERTY
Enter Class UParticlSystem like this
And add ExplosionVFXFactory
Let's implement this first
If you go this way, you just need to handle
The Fire part in the player's source file
It needs to be fired differently depending on the type of gun
So if bChooseGun is true, it means we create bullets
And if bSniperGun is true, it means it's a sniper
We'll use something called Line Trace to handle the impact
When it is else, we'll fire default gun
This is the default gun and this one is sniper rifle
Let's handle default first, we need actual bullet generation location
Yes, we need to set the location
We can do this one
This is what actual model is for our default gun
We can use the coordinates over here
The Muzzle here looks like this
And we want to generate bullets over here
So, I'll make a copy of the Muzzle
And name it Paste Socket here
Then an additional Muzzle is made
Then this is FirePosition
And let's pull the location a bit to the front
We want the bullets to be generated here
And this one must be saved
In order to use this, make sure you remember the name as well
If you press F2, you can copy it
Make sure you save it
To be for sure, save the entire file
After that, come back here
Now let's create it here
It is located in GunMesh
Write GunMesh, and GetSocketTransform
And then put TEXT with the name FirePosition
Bring the SocketTransform with that name
Make this FTransform
And write t for it
Now let's create it
GetWorld and then SpawnActor
ABulletActor so we can generate bullets
So, BulletFactory comes in
And then add t like this
It means that the bullets will be made at that Transform location
There's not much more to do anything
This would be sufficient enough for the bullets to fire
Let's try it out, so compile it
We get an error, probably made because I didn't add the header
Let's add the header like this, ABulletActor
Let's run it again, the gun's not firing
Then now let's check from the keys
The key, left mouse button is set right but the gun doesn't fire
IA is registered with no problem
In cases like this, it's better to look at some logs
Let's find out if this comes in
UE Log LogTemp and then Warning
Let's look at some TEXT
I didn't put Factory here
I will fill this up, this could be the reason
Fill it up here as well and then run it again
It works fine now, we found the problem
Finally, let's fire SniperGun
For sniper, rifle we will do it this way
Till now, for collision
We imagined an object colliding with another
That was the kind of collision we were working with
And then there was event and so on
This time, let's say we draw a line
From a point to a point
If there is collision object in the line
We will make it detect objects
Compared to human, it can be the point of view
To create a gaze like this and detect when an object is detected here
We look and it touches here
Let's create a function that can detect
In Unreal Engine, it is called Line Trace
Line Trace serves two different roles
It can utilize object channel
And trace channel
This time, let's use trace channel
To handle this
Here, write GetWorld
Write Line Trace
There are many commands like Trace By Channel
Let's use Single By Channel this time
If you look here, the variable is FHitResult and from start to end
To draw a line, you need two coordinates
This would be the locations for that
And then, what it will look at
This is the filtering
Parameter comes in here
Let's try constructing all of this
Let's start with FHitResult hitInfo
Let's write FVector with start
This is camera, CamComp and GetComponentLocation
And then there is FVector end
End value will be Start plus CamComp's aligned direction
Here, GetForwardVector
Multiply about 100m? If you want more, add more
It can as far as 1km for example
A Parameter is required here as well
There is something called FCollisionQueryParams
Write Params
Many different commands can go, but the most important would be
Excluding myself there by using AddIgnoreVector
Wrtie this to exclude myself
And then put everything in here, hitInfo and then start
And then end, the one I will be facting, ECC Visibility
And then add params
So, bool and bHit
Let's check the collision
The return value would be the bool and when collided, it will be true
The actual collision info will be in hitInfo
Therefore, if bHit is true
Then at the location, VFX will be made
So, UGameplayStatics
If you look here, you can use SpawnEmitterAtLocation
Add GetWorld here
And then ExplosionVFXFactory follows
We need to put the location which is in the hitInfo
In the hitInfo, there is a Point which is the concept of Impact
This is the actual collision location
So we've made it and add the header
And then compile it
If you run it, at the hit point you can see the VFX activating
Let's summarize everything we've learned in this session
Placing grenade launcher and sniper rifle
Setting the materials for the grenade launcher and sniper rifle Created as components of the character
Implementing functionality for the grenade launcher and sniper rifle
Implementing functionality for the grenade launcher, creating bullet actors Handles projectile object using ProjectileMovementComponent
Implementing functionality for the sniper rifle Line trace, used for collision detection
Implementing gun swapping and crosshair
At first, starting with the default gun since it's false Declared an InputAction for key input and set it up in the blueprint
SetVisibility function Handling the Crosshair by enabling or disabling the widget component