Hello, this is Youngho Lee
In this lesson, you will learn about player state synchronization
First, we will learn
how to synchronize player health
By replicating health properties
We'll learn how to synchronize and how to billboard the UI
to rotate while facing the camera
Second, we learn how to handle player shooting
In shooting processing
to give the player the effect of being shot
we will learn how to create UI and apply UI animation
We will also learn how to maximize
expression using the camera shake effect
Third, learn player death handling
When the player enters the death state
We will add a visual expression
and a UI to allow the player
to exit the game and retry
Health Property Synchronization
This time, we will look at player health
Player health synchronization will be processed
As for how the player's health is currently configured
in the actual network state, the two health values ​​are
not synchronized between
the client and the server
Let's come to Visual Studio
and first move to NetTPSCharacter's Tick function
Let's move to the Tick function in cpp
Here, we are recording printNetLog
We'll comment on it
After that, the network information
will not be displayed on the screen
Next, we will implement content
to synchronize the player's health
HP is used to indicate physical health
Here, we will use this HP value
to synchronize in the network state like this
First, this HP variable is
now properly declared as UPROPERTY
but the option to be replicated
in the network state is missing
So, let's put the Replicated option in front of this
Let's add the Replicated option like this
It's very simple
Once HP is replicated like this
What happens to the network status?
It is declared as a target for synchronization processing
Well, this has only been declared
but the processing structure that synchronizes this data
needs to be registered in this function called GetLifetimeReplicatedProps in cpp
So, at the bottom
let's add the HP value
to the GetLifetimeReplicatedProps function
If you do this, you can even include the implementation of ensuring
that the HP value is synchronized in the network state
There you go
Now, the part that is currently touching this HP will be the SetHP part
This is how SetHP currently handles HP values
Now, where do we handle this part of setting HP like this?
It has to be processed on the server
Where do you create data on the server and visualize this value? From the client
Now, let's first look at where SetHP is called again
The part where SetHP is now called is
not called directly
but using getSet Property
That's DamageProcess
In other words, where is this SetHP running now?
In DamageProcess
In this DamageProcess, we are now changing the HP value
Next, where is the damaged processor being called now?
When the server RPC gun is fired
a part of the server RPC creates this data, right?
This part of configuring logic and creating data is
the part that causes damage to users
In other words, when a client and a server exist
this DamageProcess HP stamina reduction part is executed somewhere
It's happening on the server, so this part of DamageProcess
that reduces HP like this is
working normally on the server
Then there is the part below here
This part below updates the UI
This part can be done on the server or not?
That's not possible Where should I move this part?
This will be something that needs to be implemented on the client
Now, where does SetHP run now? Only on servers
But we want to do this to express it
on the server and all clients
So, let's move
this active part of this UI in SetHP to the tick function
Let's leave HP's value part
and move to the tick function
I'll paste it at the bottom of the tick function like this
Then, the part that updates the UI will now be executed in places
where the client and server are located on the client-server and listen to the server
And then this content will also be executed in those clients
running only in the client window
Right? When there is a MainUI
its UI is expressed in the upper left corner
so that content will be expressed
When there is no MainUI, the UI floats above the other person's head
Then, this part of the HP UI just below
created using the health bar, will be updated on the screen
Are you done? Now, let's do this and build it
Now, let's go ahead and build it, so let's go ahead and run it
Do play, and the client came out like this
Now, make the other client see me
On the server side screen, I'm going to go grab my gun and go ahead and shoot
What happens when you bang?
You can see that the opponent's HP is currently decreasing like this
On the server screen
and then on the client screen, the person who gets hit is the main character
You can see that the hit target's HP is reduced like this
The two are in sync
and are working properly
Now, let's go and grab a gun on the client as well
Let's grab it and try to hit the character on the other side's server
If you bang, it shrinks, and you can see it shrinks normally
Okay?
Now, we made sure that HP is expressed properly
What about the part that keeps updating
this UI even though I haven't changed this HP value?
They said it was a waste of computational processing on the CPU
So, what are we going to do about this?
Let's process it like this
so that the UI can be updated only when the HP changes
Go to NetTPSCharacter.h
Now, it says Replicated here, and change this part to using
which means you will use the function
I'll put it as OnRep_HP
At to bottom, put UFUNCTION, void
Now, let's add this OnRep_HP function to the implementation part
Now, let's move the code that updates
the UI on the screen to this OnRep_ part
Now, I implemented it in the tick I put it in the tick like this
This part
I will add this part to OnRep_HP
OnRep_HP, I will add the relevant information to this part
If you do this, the OnRep_HP function will be called
when the HP value changes and the screen is updated
Do this, and play, then to find out what problem is there
I've already explained before
but let's try to figure it out again by looking at the screen
So, let's press the play button
go to the client side, and shoot a character on the server
Bang! Character number 1
How's this look like?
The HP on the client is being modified
but is the HP on the server currently being modified or not?
It's not working
If you look now, the HP above the client's head changes normally
ut the HP of the character on the server is
not changing properly
It worked in Tick earlier
but has not worked since moving to OnRep
This OnRep_HP This function is called only from where this event is
This is a function that is called only on the client
Since the change was made on the server
the client receives and processes the change event
which is only called on the client
So, what should I do to fix this part?
OnRep_HP is a code from the server
if you explicitly call it once like this
At that time, let's rebuild it so that OnRep_HP can be executed and the results can be seen
Try running both the server and the client
Now, let's see if it works What happens if you bang the server character?
The HP bar on the character's head is decreasing
You can also see that the HP bar
in the left server window decreases
Now, similarly, let's go and use the server character here
Bang! Then, you can see that the HP bar in the left server window is now decreasing
and on the right, you can also see
that the character's HP is decreasing along with this part at the top
You can see that this and this are being synchronized with each other
As I'm playing now, I think this part is very annoying to the eyes
So, let's go ahead and put the character on this side first
Next, let's say the server character
shoots the character on the client
It's the server window on the left now
Bang! I'm going to shoot
But on the left, you can see that the user's HP bar is displayed normally
So that the user's HP bar is decreasing like this
But oh, on the right, in the client window
Is the character's HP bar visible or invisible in the server window on the left?
You can't see it
Why is that so?
Because your back is turned
If you go to the front, you can see it
What if you go to the back? You won't see the HP bar
Let's continue to modify this by using a technique
to display HP according to the character
We call this billboarding
Go to Visual Studio
Let's move to the Tick function and process this
Let's try processing the billboarding using the Tick function
There is no need for this content at the bottom of the Tick function when it is the main character, right?
What kind of character?
If it's not the main character but an opponent
It has to be shown on this screen
You have to process HP bar to look at me
So, if there is hpUIComp
only when hpUIComp is showing on the screen
you can handle it like this so that it looks at the camera
If you look at this value now, getVisibleFlag returns a bool value
So, if this HP bar is shown on the screen
and the HUD above the character's head is shown
I will process the billboarding and add this content
Then how can you get it?
You can get it using vectors
You can use simple subtraction of vectors
Now, we need the first camera's location and the UI's location
So first, in the vector
Please enter the cam location
It does not get the camera in NetTPSCharacter, but the camera is on the other side
You can get the camera on the other side like this
All you have to do is find out which character is using the main camera on the screen
and bring it to them
So they can be obtained like this
If you look at UGameplayStatics, you will find something called getPlayerCameraManager
Using this camera manager, we can determine
which cameras use the viewport
You can find out which camera is active
Now, let's put the world here
So here is the player index
I'm going to find the 0th PlayerController
Then, if you look there, you can get getCameraLocation information
Since we need this location information, the camera's location information
Next, he said he would subtract the camera's location, who?
Since the UI is looking for the direction toward the camera's position, from the f vector
I will get a direction vector
How do you get this?
Subtract from camera location
If you enter getComponentLocation information in hpUIComp, the direction is obtained
Let's set the z value
to 0
Then, add the setWorldRotation information
and the direction to hpUIComp
We'll put it in normalize getSafeNormalize
Get it with getSafeNormal like this
Let's add ToOrientRotator to it like this
Then, change the vector to this rotation and add it
This means that normalization makes the size one
Let's make it like this: make it a rotator and put it in
Now, let's build
Now, if you go and play and play again
No matter which direction your character goes, what is the opponent's UI like?
It's
looking at us correctly, right? But there's a downside
Ah, why wasn't it visible to us until now?
Because my back was turned, my main character's
UI bar didn't show the HP bar like this
but when I forced it to look at the camera and made it look at me
this was finally revealed
It was just that it wasn't visible
When I made him look at the camera
this problem arose
So, should I show this or not?
you don't have to show it
You only need to show this HP bar, not this one
So, let's try to process this
Now, let's go to Visual Studio
When should this hpUIComp be shown, and when not shown?
When MainUI is on the screen
should this hpUIComp be shown or not?
You shouldn't show it
And when there is no hpUI since it is the other person's
the hpUI health bar must be shown above his head
So, I will edit the part that handles this
Now, what the function is is InitUIWidget
What are we doing in InitUIWidget?
I'm doing this part to create the MainUI
Right
Then, since there is a MainUI, let's make the health bar above my head invisible
This content should be included
Because the MainUI makes the health bar visible
The UI displayed above my head must be processed like this
which is invisible
If there is hpUIComp, it will be there
but just in case, I am checking it like this
How about adding false to the SetVisibility property in hpUIComp?
If it is an opponent's character other than the main character
it will be displayed, and the presence of a main character means that there is a MainUI
In this case, we will process hpUIComp so that it is not visible
but the default is now set to true, so it is shown
so that we will handle it like this
Now, let's build it like this
Now, if you succeed, let's go and play again
So now, will the HUD appear above my head or not?
It doesn't show up, does it?
If you play now, you can see that
only the opponent's HP bar appears above their head
Now, no matter which way I go, the UI is rotating while looking at me
We even processed the billboarding so that the player's health bar can be seen
Using this, I completed all player stamina processing
Shooting and Death Effect
This time, we will look at handling player shoots
Among the provided assets, if you look here now
there is an image file called DamageBloodScreen.png
Let's add this image to our project
Let's add DamageBloodScreen to the UI folder by dragging and dropping it like this
Then it came in like this
Now, let's add some UI actions
to show this DamageBloodScreen
So here is WBP MainUI Open the WBP MainUI blueprint
Now, let's add an image from the palette
Let's search for an image in the palette
and add it under the canvas panel
Then, it is added at the bottom like this
Let's name it DamageUI
Then, go to the details window on the right
and since the anchor value will fill the entire screen
let's select this part at the bottom right
Let's
set offset left and top to 0
offset right, and bottom to 0
This will result in this image being filled
Next, we will drag and drop the DamageBloodScreen
that we added to the project as an image
into this brush part like this
Then it will look like this
So, when we are shot
we will process it like this to display it on the screen with this look
Now, it's good to show it like this
but let's add an animation to this UI that
shows it suddenly and then slowly disappears
There will be an animation in the window menu
If you look fourth from the top, there is an animation
Select it, and the animation window will open
Here, click the animation button
Let's name this animation DamageAnim
DamageAnim, this is why it goes into DamageUI
Select DamageAnim and press
the track button on the right, then DamageUI will appear at the top
We have selected several UI widgets here
and among them, we have selected DamageUI
hen DamageUI appears
Here, to make this UI visible or invisible on the screen
you can change the Render Opacity property
Let's add a Render Opacity property
and its contents to the animation
There's DamageUI on the track here
Shall we press the plus button?
Then, a pop-up window will appear
and it will say Render Opacity
When you click, it will appear like this
You can see that a keyframe was registered here at the very beginning
We want it to fade out over 2 seconds
so we'll put this timeline bar at 2 seconds
and click the plus button in Render Opacity
There is a plus button Click the plus button
Then, you can see a keyframe inserted at the 2-second mark
Now, you can add it to the 2 second part like this
Now, it's like this Then, what do you want to happen in these 2 seconds?
As time goes by like this, I want to
increase the transparency of this Opacity value and process it like this so that it gradually becomes blurry
In other words
what do you want the keyframe value to be in the last 2 seconds?
I hope it becomes 0 Select it here
select the keyframe at 2 seconds
and if you look down here, there's Render Opacity
Let's change the value of this part to 0
Now, if you do this
the current value of the keyframe at the beginning is set to 1
It is set to 1 like this
As this value gradually decreases to 0 as the animation timeline progresses
it becomes 0, right?
I want to make it so that it is processed like this
Should the damage effect be shown on the screen first?
At first, it must be 0
So, if you select anywhere in the blank space like this
how about making a selection in the animation window?
It is not checked right now
Now select DamageUI, and again
the animation window is currently disabled
The details window on the right will have a Render Opacity value
In the search section of the details window
If you search for Render Opacity, it is currently set to 1
Let me change this to 0
Then, of course, the initial default value will be 0
But the animation plays
So, let me select DamageAnim here
In the animation window, it will appear on the screen and then, when you press play
it gradually disappear
Are you done?
Now, we made an animation like this
Now, let's click compile
and display this UI called DamageAnim on the screen
and when we got damaged
I will do shoot process effect appear on the screen
Let's move to Visual Studio
and move on to the new MainUI
Come to the MainUI h header file
and at the bottom I will make it public
and add the DamageUI animation
Now, enter the UPROPERTY and enter Edit Default Only
Next, we will use the meta keyword
and enter BindWidgetAnim
Generally, when we bind UI, we only use BindWidget
But since we want to play animation
we need to add BindWidgetAnim
Then, add a transient to the back
and put the category My Settings
class UWidgetAnimation
I'll put it in DamageAnim Oh, I put it in capital letters DamageAnim like this
It must have the same name as the DamageAnim created here
If it comes out like this, it will bind automatically
Now, let's create a function that plays the shoot handling animation
that plays animation through the UI animation
Void PlayDamageAnimation, let's create a function like this
Shall we add the implementation part?
Add PlayAnimation to the bottom of the Main UI CPP
Here, PlayAnimation
Here
UWidgetAnim is designed to insert animation here
Let's add DamageAnim like this
Then, when the PlayDamageAnim function is called
the DamageAnim shooting processing animation will be called internally
So when should this be called?
What happens when a player's HP decreases?
It means that you were shot
It means you were attacked
So where does this part go?
OnRapHP to NetTPSCharacter
What OnRapHP does is
that it is code that runs on the client
Why is it running on the client?
Since this has been shot, the HP value is changed
OnRapHP is called
and then we update this UI
And who should I show the damage effects to?
Only when you're the main player, right?
That means when MainUI is present
MainUI is the screen where the user's HP is displayed at the top left of the screen
You only need to show the damage effect only for the characters with this MainUI
So, under this MainUI's HP
shoot process effect
Let's play this part
Let's call PlayDamageAnimation in MainUI
Build it
There you go
Let's go and play it now
You need two players
I will make the server mode window appear separately to make it visible on the screen
The server window opens, and then the client window opens
I'll grab the gun on the server first and shoot the client
Look at the client window on the right What happens when you bang?
The shooting process effect is playing properly
and let's check it out on the server
This time, you have to look at the window on the left of the server character
Since it is fired from the client, if you fire from the client
you can see that the server window on the left
properly shows the shoot processing effect
If you get to this point
the effect of dealing with hits when you get shot a little more
may be a bit ambiguous as it maximizes immersion
So we'll add one more thing to this
I will shake the camera like this, and when I get shot
I will shake the camera slightly to make the damaging effect
look more realistic
It's called a camera shake, and in the Blueprints folder
in NetTPS Blueprints folder
we'll handle this part by creating a camera shake Blueprint
Now, right-click on the Blueprints folder
Then click on the Blueprint class
Let's search for a camera shake in AllClass
Then, CameraShakeBase appears
Select CameraShakeBase
Let's name it BP_CameraShake
Let's double-click BP_CameraShake to open it
Now, what we're doing is very simple In this detail window
there's a RootShakePattern on the right Let's change this part to a wave
Select Wave Osillator Camera Shake Pattern
and open it
I want to shake the screen in all directions
when I get shot
I'm trying to change the position value like this
and shake it around
So, using only the location information without processing the rotation value
let's shake the screen
In Location, there is a Location Amplitude Multiplier
It has become amplitude, which means how much should we shake?
Next, Frequency refers to how often
and how quickly to shake
Let's set the amplitude to 2
the Location Amplitude Multiplier to 2
and then the Frequency Multiplier to 15
Leave the rest alone
Then, since the timing part needs to be moved to the bottom and shaken very briefly
I do this for about 0.25 seconds
Next, we will set the Blend In and Blend Out Time to 0.05 seconds each
Like this
I'll set the duration to a very short 0.25 seconds
so that it can be played right when the blend switches
set the Blend in Time and out to 0.05 seconds
You can click compile and close BP CameraShake now
Then, the Blueprint did all the work so that this CameraShake could be called
Let's move to Visual Studio
To the bottom of NetTPSCharacter in Visual Studio
let's add this
Now, let's keep adding it separately by making it public
I will add the part related to the camera shake here
UPROPERTY(EditDefaultsOnly)
Now, let's put the category as UI
Shall we put in damage? Since this has nothing to do with the UI
I'll put it like this The category, damage
Next, let's use TSubclassOf class UCameraShakeBase
and add damageCameraShake here
This will allow us to put our Blueprint
into this variable called damageCameraShake
o let's do this, and now let's move on to the cpp file
Coming to NetTPSCharacter.cpp
When?
We will play the shooting processing effect
and then process it here in OnRep HP to shake the screen
to play the camera shake effect
So I'm going to handle damageCameraShake
when it exists
Now, just put the auto in it and call it using PlayerController on your PC
It's called Cast APlayerController, and this is a Controller
Of course, there is a Controller if there is a MainUI
Now, the PC has
ClientStartCameraShake on it
Here, you can add damageCameraShake like this
This will create the effect of shaking the screen
Let's build
and go to Unreal Editor
Now, open BP ThirdPerson in the Blueprint folder
If you search for damageCamera, damageCameraShake will now appear
It is set to none here
but select this part with BP CameraShake like this
Shall we click compile and go and play?
Now, if you pick up a gun and shoot an opponent
see what happens on the client screen on the right
You can see the screen shaking along with the damage effect
This is how I worked on the camera shake
for being shot
Then, the processing of the player being shot has been completed
Now, we will look at handling player death
I will change the screen to a gray tone
then, such as whether the game should restart or end
I will implement this content, which even displays a UI
So currently, when the screen is like this
the character looks like this
and when the player dies, it is shocked to a gray tone like this
After that, I'll put the manual
up here
Such as whether to restart or end
Let's work on a UI that displays something on the screen
So, in the animation folder
there will be a montage, a death montage
If you look here, it's not an MM_Death montage
but an animation sequence. Let's double-click on it to open it
It's MM_Death and front01 is written like this
Now, when this animation runs
and reaches this point
I will trigger an event that changes the screen to a gray tone
So, should we create a notification event here?
Click the right mouse button
and on the number 1 that says notify
click the right mouse button
Now, add Notify
Then, new Notify
Should I put DieEnd in it?
When the DieEnd Notify event occurs like this, we try to process it
Now, I will close this window for now
Let's move on to Visual Studio
Now, go to the header file in Visual Studio
Move to the NetTPSCharacter header file
I will add information related to death processing to this part
I will create a function called void DieProcess
and in this function
I will implement what to do when the player dies
So, shall we try adding this function?
Okay?
Now, this is NetTPSCharacter.cpp
Now, what content
are you going to add to the header?
When the animation is played
this notify event called DieEnd occurs
A Notify called DieEnd will be played
and when this event occurs
we will receive the event
and call this DieProcess from there
So here, we'll gray out the screen
pop up the screen with the UI, and do other things like this
So NetTPSAnimation to receive that Notify event
Let's move to the header file
and apply the necessary notify event
Now, if you look here, there is a reload animation notify event
Similarly, I copied and pasted
this below and at the bottom
This time, it goes like this: AnimNotify DieEnd
Then, when the DieEnd animation is in progress
and DieEnd is called
this function is called
when notify is called
Now, what we will do in this AnimNotify DieEnd function is
call the DieProcess function in the player
So, there must be an if player first
After that
the screen should be grayed out only for the main player
which is unnecessary for the opponent
How do I tell
if this character is currently the main character?
That means that it is being controlled by the PlayerController, right?
In other words, it is an autonomous character
Once it becomes an autonomous proxy
it becomes locally controlled internally
In the case of a server, it is the authority
What handles these internally?
It's the isLocallyControlled function
In other words, internally
it checks whether it is the player I control
At this time, the message is that DieProcess in the player will be called
At this time, when DieProcess is called
DieProcess in NetTPSCharacter is called
How do I make the screen gray out as if it is disabled
What do I do with this?
What I will change in the Unreal Editor is, internally
in the Blueprint
there is a BP ThirdPerson character
If you go to the following camera, there is a saturation option among the camera options
Should I enable the saturation option with this value?
And if I activate this value
and change it to a black tone
shall we do it randomly?
It means putting it like 0, 0, 0
What will the screen look like if I play it like this?
It comes out in a gray tone like this, everything is hazy
That's right, the whole world becomes gray
What I am saying is that we will make it like this
So, in the code
I am going to set this value to 0 0 0
for this saturation in DieProcess
Right?
If you leave it like this and play again, it will come out as it was
Now, in DieProcess, let's add something here that changes that value to 0, 0, 0
Go to DieProcess in Visual Studio
Now let's first import PlayerController Cast APlayerController
Here, this controller has an unconditional value, why?
How is it done in animation?
When there is a player, right, when there is a player, and local control is in place
we do this to that player
This means that there is a PlayerController
If we want to do something first
since we are done, we want to launch the UI and do this work
So, at this time, to show the mouse on the screen
there is a thing called SetShowMouseCursor in PlayerController
Let's set it to True here
so that the mouse cursor is visible on the screen
then gray out the screen as shown above
Let's put it in the bottom part, and there's GetFollowCamera
This Follow Camera has PostProcessSettings
Let's work on Color Saturation here
In addition, it is FVector
and the value is 0 0 0. At the end, it gives an alpha value of 1
Now, here we have to take over 4 FVectors
Now, let's build it like this and look at the results
So let's play and let the other person play, too
I'll go and grab a gun on the client and shoot the server character
If you shoot three times, how about going to the server window on the left and looking at it?
Can you see that it has now changed to a gray tone?
It looks like this, right? Then there is also a mouse cursor, right?
Do you see it like this?
It worked normally
But on the other hand, why didn't it work when I did it on the client?
Now, let's grab the server and shoot the client Bang, bang, bang
When I shoot the server from the client, it works normally
but what happens when I shoot the client from the server?
The damaged animation is not displayed properly on the screen
and the colors are also not visible
Why is this part like that?
What parts are being processed in our code now?
DieProcess plays in the animation
That is, it is client code that plays in the animation
Right? Since it is client code, if it is sent from the client to the server
all of these details will be applied to the server
so it will be processed properly
However, this content will appear
because the server and client are not properly distinguished
Shall we check it through the code?
Let's move the DamageProcess function
In DamageProcess, the HP value changes
when the user is shot
Where does this part run? The part that converts to data is
currently being executed on the server
What is happening on the server when the current HP value is 0?
They are treating it like this when they die
But what happens to IsDead now?
Is it being replicated? It's not
So, when changing from client to server, the server is the client
showing properly in the server character
However, the server attacked the client
The one in the server window is now in a separate window
from the one in the client window
It was in a separate place, but it attacked
It attacked this person, and in this window, this should be applied and grayed out
but this is set to true only on the server
and there is no way for the client to receive this data
So, this means that the screens are out of sync
Because the fact that it's dead does not come in
Right, it has to be IsDead What do we do with IsDead?
I'm doing animation processing and stuff like that right now
Yes? Where is IsDead handled?
Coming to Unreal Editor, there is ABP Manny in animation
Yes? If you look here, you will see an IsDead option
If you look at NetPlayerAnimInstance
there is code that synchronizes
the IsDead value and the player's IsDead value like this
In this update animation
when this value becomes true, it becomes true
a death animation appears, and this should be processed
What is the problem now?
It works on the server, but does it work on the client?
It doesn't now
I changed it on the server, but the client
hasn't yet synchronized and received this data
So we need to take care of this part
For this purpose
will you synchronize the IsDead property in NetTPSCharacter?
You don't have to do that
How? This part doesn't have to be here, then where?
When the client code is executed
IsDead on the client becomes true
So, instead of putting this part here
this HP value is
synchronized anyway
so I'm setting the HP value here like this
so this HP is currently being replicated
With this HP value alone, we can save packets in the network state
and not synchronize it
Instead, we can just take this value and set it to true here
Where will we take this part?
In DamageProcess, if HP is less than 0
Press Ctrl+x to cut the IsDead true part
Then, you enter the OnRep HP function
What should we do now so that the OnRep HP function is entered
and the relevant content is attached here? At this time, is HP less than 0?
Then, how did he die? Let's deal with it like this
Where does OnRep HP run?
It runs on the client
This means that when executed on the client, it gets the HP value and processes it as if it is dead
Let's build it
then go to Unreal Editor and play again
There was no problem when switching from client to server, right?
Now, let's use the client again on the server
Bang, bang, bang, you can see
which parts of the animation and screen are displayed normally, even the blurry parts
So, first of all, it was about handling death
and there may be questions about what other problems could arise at this time
I'll go and shoot the character
Bang, bang, bang, I got rid of it
He's dead, right?
He's dead, but I'll go and shoot him again
When you shoot, what happens? The screen keeps shaking Why? Because it's keep shot
I think we need to do something to prevent it from getting hit when it dies
So, at this time, when IsDead is true in OnRep HP
if you are still holding the first gun
drop the gun you are holding
and disable the collider to prevent further collisions
Do it like this, right?
After that, can the character keep moving or not? It won't work, right?
Let's prevent the character
from moving
Now, let's check again what's going on right now
I grabbed the gun and shot the other person
First, there is a problem with the damage dealt from repeated hits
And then I'll move it around on the client screen here
Can you see that it keeps moving even though it's dead?
The movement continues
There's this part that prevents him from moving, and even though he's dead
let's say he goes and grabs the gun
The other person is holding a gun now
Do all these things work or not? That's not possible
Should the client even go and grab the gun first?
Got it
Now let's go to the server this time, grab a gun and shoot the opponent
I think there's a problem with this because he keeps holding the gun in his hand
even though he's dead
Drop the gun when you're dead
I will process this like this, so I have included these three contents
So that made us drop the gun we were holding
What was our ReleasePistol? It was the input to release the gun, ReleasePistol
If you go and look, you will see the information about releasing the gun in this ReleasePistol
So what we're saying is that if you simply input ReleasePistol
releasing the gun internally will happen automatically through server communication
You can do this to drop the gun you are holding in OnRep HP
Now, all you have to do is use ReleasePistol and add that FInputActionValue value here
For FInputActionValue, we will only add an empty constructor function
Why?
ReleasePistol does not process any input values
but processes the input as it comes in
so you only need to enter this part here
Next, set SetCollisionEnabled that disables the collider
to No Collision on the CapsuleComponent
Then there will be no more crashes
and if you look, there's also mesh
In addition to CapsuleComponent, there is also mesh here
Even in mesh, colliders are attached separately
So, let's also change CollisionEnabled in the mesh
Press Ctrl+D to process NoCollision
in Getmesh this time
And since we wanted to prevent the character from moving
we will import the GetCharacterMovement component
and handle it like this: DisableMovement
Then, the user will not be able to move
Now, there is one thing you need to know here
I told you that this runs on the client
This is the structure that is currently being executed on the client
This is my main character in onlap right now
There is a user character with a different sub-character over there
He currently has a gun like this
If I bang like this, then this function will be called internally
Since this is a client, it is his own
so things like being deactivated when he is this guy or this guy will also be expressed
Why? When there is a main UI But if it's the other person
you must do these things so they can't keep guessing
That's what dropping the gun is all about
Okay, I'm going to drop the gun just like this
I dropped it
Now, this is what happened with ReleasePistol
Right, but what happens when you use ReleasePistol?
I should leave mine
but for the ones on the main character
I need to properly receive input from ReleasePistol, but this one doesn't work
What I'm saying is that we only need content about dropping the gun
In other words, let's go inside ReleasePistol
Now, if you look here, when you use ReleasePistol, what are the opponent's like now?
Using serverRPC, ReleasePistol is automatically fired when the user dies, which comes in
This condition is required
If it is not locally controlled, it should not be processed
This means that only the one currently controlled by the main can request server RPC now
I will modify the content to do this only when autonomous
Now, let's process the build like this
Now, if you go and play
you grab a gun and shoot, and now you won't take any damage to your opponent even if you keep shooting
Right, so either he can move, or he can do something, or he can't
Up to this point, when dealing with death
I worked on various things like animation, UI, and dropping the gun
Well, it ended up like this
Now, let's try to restart or end the game so that the Game Over UI
can appear on the screen when it is in a dead state
Now, open WBP MainUI from the UI folder We already opened it
In addition, we will take care of this so that the Game Over UI can be displayed
Here, we search for a horizontal box in the palette and add it to the canvas
Then, here comes the horizontal box
I'll name it GameOverUI
Let's put it as GameOverUI
Now, shall we add a button?
Let's add a button and register it with GameOverUI
Because it is a horizontal box, it will be attached to the side like this
And one more text
Make the widget common, take the text widget, and add it to the button
Okay, let's make it like this
Press Ctrl+D to press the button and Ctrl+D to copy two things
I'm going to put a spacer between these two
Let's search for a spacer widget in the palette
and add it between this button and the button like this
If you highlight the spacer button like this, it will look like this
I named the button at the top btn_retry
Below
I will enter btn_exit
For the text value here
enter retry as the value
Enter retry like this
Next, we will put exit as an exit
Now, I'm going to select this Game Over UI
and I'm going to align this to the exact center
Let's align it to the center and add 0 to Position X
Next, we will set the alignment to 0.5
Should I make it a little bigger?
I will set the Size X to about 600
Let's set the Size Y to 50
and I'll also lower the Y value of game Over
Let's put it like this? I'll put it like this
I'll put it in like this: about 155
Next, select btn_retry
and set the size part, fill
Then it will be full
I will set the background color to a slightly distinguishable blue color
Then select space
Select fill again, and there will be a space in the middle
Lastly, select btn_exit and similarly select fill
Then, I will set the background color of this exit to red to distinguish it
Then, compile it so that it appears on the screen like this
Now, with the content, 'I will make this UI appear like this,' let's implement it with this content
Now, should this be shown on the screen at first or not?
It shouldn't be visible, so GameoverUI will first
set the Visibility property to hidden
At first, this UI will not be visible on the screen
Now, I set the Visibility property to hidden
And in the code state, when the game is over, and you die
I will transform it like this so that this screen appears
Go to Visual Studio
and navigate to the MainUI.h file in Visual Studio
At the bottom
Public
I will add information related to GameoverUI
So, set UPROPERTY to BlueprintReadWrite
Now, let's connect the two in meta and bind them to connect them
Connect it with the BindWidget class U horizontal box
The name was GameoverUI, and if you look here, the name is exactly like this on capital letters
Let's insert the GameoverUI value as it is like this
Like this
Just duplicate the one above
This time, it was class UButton
The button said btn_retry
Press Ctrl+D to get one more class UButton
This time it was btn_exit
You can do this in DieProcess so that they appear on the screen
I do build processing here, which can be seen on the screen in DieProcess
Now, the compile was done normally without any errors
Now, let's move to NetTPSCharacter's DieProcess
At this time, it is grayed out like this, so it is not visible on the screen, right?
You made the whole world turn gray
Here, we will finally display the Die UI
I have GameoverUI in MainUI
There will be a SetVisibility property in GameoverUI in MainUI
In addition, we will add the visible property like this
At the top
let's write #include to use the horizontal box
To the component
we will add the HorizontalBox h file
Now, include the HorizontalBox h file in the component
and you can use it
So, let's try building again
Then, when it dies, the screen is treated as if it is deactivated
and GameoverUI is displayed on the screen
Let's go and take a look, play
Should I grab a gun and fight my opponent?
When you shoot, what happens when it dies?
A retry button and an exit button appear on the screen
Then the screen becomes blurry and gray-toned
and nothing has been connected yet, so it's like this
So, we've done processing when it's died
I even completed handling player deaths
Let's summarize what we learned in this lecture
Health Property Synchronization
Health member variables are synchronized through replication and UI update logic is implemented
Handle it in the Tick function to continue processing attribute replication, and switch it to the OnRep event function to reduce CPU processing operations
Learn how to process billboarding so the HP bar remains visible to users
Shooting and Death Effect
Created UI and animations to handle hit effects By applying camera shake, a highly immersive shooting effect is expressed
Insert a notify event into the animation that handles the death state, and write logic that can process it using a callback function at the desired timing
By activating the Saturation option in the camera's post process, the screen turns gray when in a dead state
Display UI in death state to allow choice between restart and end
The End