How to do damage – advanced

There are lots of ways for dealing damages in games. I will do more advanced stuff:

  • Damage will be calculated from weapon and ammo type,
  • Critical Chance will be calculated,
  • I need to see what’s the damage and if there was a critical hit (UMG),
  • I need to see how much HP enemy have,
  • I want to have different damage depending on which body part I shoot, (eg head, leg etc)

Let’s gets started!

This Tutorial has been created using Unreal Engine 4.8.2. 
Make sure you are working on the same version of the engine.

Unreal Engine 4 has damage system implemented. You can read about it here. I will use my own system in this tutorial because I have different data than ApplyDamage from engine.

Create Damage Interface.

Let’s create new Blueprint Interface named I_TakeDamage. You can read more about interfaces here. 

There should be one function: TakeDamage

I_TakeDamage

It will be used for all actors that implement this interface. For example if you want Bottle to take damage just implement this interface in its class preferences. Of course currently we aren’t firing this interface so it won’t work yet.


Updating BP_BaseWeapon. 

We need to do some changes to BP_BaseWeapon.

In CalculateShootInformations function we need to change Line Trace by Channel  to Line Trace for Objects.

LineTraceForObject

And add these variables:

  • MinWeaponDamageModifier (float, default 0.5),
  • MaxWeaponDamageModifier (float, default 1),
  • CritDamageModifier (float, default 2),

Now create new function AddDamageTo with inputs: Hit Result (Hit Result), EndLocation (vector)

We will call our interface from this function.

adddamageto

We need to update Fire function because some of the functionality (CalculateShootInformations) was implemented in BP_Weapon_Pistol. I want to have this in main class so I won’t be copying nodes to other weapons.

bp_mainweaponfire

So we are spawning effects and we are firing AddDamageTo function from here. After updating Fire function you would need to delete Fire events from BP_Weapon_Pistol and other weapons that extends BP_BaseWeapon.

So Fire in BP_Weapon_Pistol should look like this:

FireInWeaponPistol

Thanks to this change every weapon we will extend from BP_BaseWeapon will have deal damage functionality.


Create Damage Feedback UMG.

Create new Widget Blueprint named UI_Debug_DamageInfo. It shouldn’t have Canvas Panel. Root should be Overlay.

It contains two text block: TextBlock_Damage and TextBlock_TextCrit in this video you can see the widget. Hope you will be able to create something like this.


Creating Damage Feedback actor.

Create new blueprint based on Actor and name it DamageFeedback. Add some variables:

  • Damage (float, editable and expose on spawn),
  • WasCrit (bool, editable and expose on spawn),

And in components (Viewport) add Scene component as root and add Widget Component. In 4.8 Widget Components are still in experimental stage but they should work correctly with our simple graphical feedback.

Widget Properties:

widgetproperties

Widget shouldn’t have collision enabled! Create Begin Play and assign earlier created UI_Debug_DamageInfo widget.

set widget


Create Health Bar UMG

Create new Widget Blueprint named UI_Debug_EnemyHealth.

As in DamageInfo Widget this shouldn’t have canvas panel. Instead add Overlay. Add a progress bar to Overlay and set Alignments to fill. Now in Event Graph create new function UpdateHealthBar.

updatehealthbar

This will update progress bar depending on Current and Max variables. You could use UMG binding for this but I have seen that they are called on Tick so it isn’t so optimal.


Creating Enemy

Create new blueprint extending from Character name it BP_BaseEnemy and add variables:

  • isDead (bool),
  • CurrentHealth (default 100),
  • MaxHealth (default 100),

Add Begin Play and assing MaxHealth to CurrentHealth.

healthset

MaxHealth will be used in later posts as a gameplay balance value.

Now let’s add health progress bar as a Widget Component. Here’s the properties:

healthbarproperties

Change Collision for Mesh so traces from weapon will block on enemy mesh.

meshcollision

Create new function UpdateHealthBar:

updatehealthbarinenemy

And another function ModifyHealth. Input: HealthToModify (float) and Output: IsDead (bool)

modifyhealth

Last function: CalculateDamage.

Inputs:

  • Damage (float),
  • CritChance (float),
  • CritDamageModifier (float),
  • WeaponDamageModifier (float),
  • HitInfo (Hit Result)

Outputs:

  • DamageTaken (float),
  • WasCrit (bool),

Local variables:

  • Local_WasCrit (bool),
  • Local_CurrentDamage (float),

calculatedamage

This function is calculating damage and returning it.

Now in Class Settings add I_TakeDamage interface as implemented interfaces and create new event I_TakeDamage.

takedamage

That’s all here. Now the most time taking part…


Implementing Body Parts

I want to use Physical Materials to check which body part was hit instead of calculating length. It will be faster but it require some preparations.

Go to Project Settings -> Physics and add those to Surface Types:

surfacestypes

It can be done quicker if you go to Config folder (YourProject/Config) and in DefaultEngine.ini add those to [/Script/Engine.PhysicsSettings]

+PhysicalSurfaces=(Type=SurfaceType1,Name=”Metal”)
+PhysicalSurfaces=(Type=SurfaceType2,Name=”Flesh”)
+PhysicalSurfaces=(Type=SurfaceType3,Name=”Glass”)
+PhysicalSurfaces=(Type=SurfaceType4,Name=”Concrete”)
+PhysicalSurfaces=(Type=SurfaceType5,Name=”Flesh_Head”)
+PhysicalSurfaces=(Type=SurfaceType6,Name=”Flesh_Body”)
+PhysicalSurfaces=(Type=SurfaceType7,Name=”Flesh_LeftArm”)
+PhysicalSurfaces=(Type=SurfaceType8,Name=”Flesh_LeftForearm”)
+PhysicalSurfaces=(Type=SurfaceType9,Name=”Flesh_LeftHand”)
+PhysicalSurfaces=(Type=SurfaceType10,Name=”Flesh_LeftUpLeg”)
+PhysicalSurfaces=(Type=SurfaceType11,Name=”Flesh_LeftLeg”)
+PhysicalSurfaces=(Type=SurfaceType12,Name=”Flesh_LeftFoot”)
+PhysicalSurfaces=(Type=SurfaceType13,Name=”Flesh_RightArm”)
+PhysicalSurfaces=(Type=SurfaceType14,Name=”Flesh_RightForearm”)
+PhysicalSurfaces=(Type=SurfaceType15,Name=”Flesh_RightHand”)
+PhysicalSurfaces=(Type=SurfaceType16,Name=”Flesh_RightUpLeg”)
+PhysicalSurfaces=(Type=SurfaceType17,Name=”Flesh_RightLeg”)
+PhysicalSurfaces=(Type=SurfaceType18,Name=”Flesh_RightFoot”)
+PhysicalSurfaces=(Type=SurfaceType19,Name=”Metal_Head”)
+PhysicalSurfaces=(Type=SurfaceType20,Name=”Metal_Body”)
+PhysicalSurfaces=(Type=SurfaceType21,Name=”Metal_LeftArm”)
+PhysicalSurfaces=(Type=SurfaceType22,Name=”Metal_LeftForearm”)
+PhysicalSurfaces=(Type=SurfaceType23,Name=”Metal_LeftHand”)
+PhysicalSurfaces=(Type=SurfaceType24,Name=”Metal_LeftUpLeg”)
+PhysicalSurfaces=(Type=SurfaceType25,Name=”Metal_LeftLeg”)
+PhysicalSurfaces=(Type=SurfaceType26,Name=”Metal_LeftFoot”)
+PhysicalSurfaces=(Type=SurfaceType27,Name=”Metal_RightArm”)
+PhysicalSurfaces=(Type=SurfaceType28,Name=”Metal_RightForearm”)
+PhysicalSurfaces=(Type=SurfaceType29,Name=”Metal_RightHand”)
+PhysicalSurfaces=(Type=SurfaceType30,Name=”Metal_RightUpLeg”)
+PhysicalSurfaces=(Type=SurfaceType31,Name=”Metal_RightLeg”)
+PhysicalSurfaces=(Type=SurfaceType32,Name=”Metal_RightFoot”)

We have types added but now we need to create Physical Material for each of them. Names should be the same (PM_SurfaceTypeName) for example PM_Metal_RightFoot.

Open created Physical Mat and change Surface Type should correspond with name. For example here’s my PM_Flesh_RightFoot.

SurfaceTypeAndDamage

One important thing: we are using Desctructible Damage Threshold Scale as our Damage Scale. So for head it should be 1 and for foot it should be 0.1 – use values as you like!

I know – lot’s of clicking but this need to be done only once so be patient :)


Implementing Physical Materials

Create new blueprint extending from BP_BaseEnemy and name it as you wish – he will be used only for tests. Set mesh to hero TPP. Compile and add this character to your level so you can shoot at him.

Go toHeroTPP_Physics and when selecting bodies you can select Physical Material for the body.

bodypartsmat

Now assign Physical Materials to body parts and you are done! i know that we could create Head, Torso, Leg instead of LeftArm etc But these will be needed later when I will destroy body parts.


Updating ImpactEffect

If you want to see different effect on different body type of character you need to update your ImpactEffect actor.

impactactor

Thanks to this system I’m able to define body parts, calculate damage and crit chance!


Creating ShooterTutorial takes a lot of my free time.
Buy Now Button
If you want you can help me out! I will use your donation to buy better assets packs and you will be added to Credits /Backers page as well.

Implementing game is taking time but writing about this is taking much more effort!

4 thoughts on “How to do damage – advanced

  1. Pingback: First Enemy – Behavior Tree / Shooting at Player | Shooter Game Tutorial

  2. Pingback: Creating a Shotgun | Shooter Game Tutorial

  3. “Showing” how to do the UI widgets with video is just AWFUL. Please stop doing that and do proper written tutorials for these like you are doing for the othe blueprints.

    Like

    • To learn UMG I would need to create video tutorials. Unfortunately I don’t have time for it :( UMG designer is simple to learn and I’m showing hierarchy in the video. If you don’t know how to create hierarchy just take your time and add some widgets in the designer – play with them. What I would like to learn is UMG communication, not visualization in designer. Hope you understand!

      Like

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s