Plug and Play Melee Tutorial

You guys requested melee tutorial and I’m right after game jam where my colleague (cheers Tomek!) did really simple but powerful melee weapon. This tutorial will be about:

  • How to do melee damage,
  • Create basic weapon class to drive melee damage,
  • Weapons can be added to AI characters as well and they will do melee damage to others as well (Player and other AI)
  • There will be two versions: one without any additional preparation and second one in which you need to add sockets to weapon mesh.

So, lets go!

Used Assets

In this tutorial I have used Animated Medieval Bludgeoning Weapons Pack which basically isn’t needed in this tutorial but with animations it’s easier to show you guys how to do melee damage.  (btw hope Ironbelly will do more first person medieval animations like two handed swords, dual weld weapons etc.

So basically what you need is:

  • Weapon Mesh – as skeletal mesh,
  • Hands with some animation because information when to start/end melee will come from animation,

Base Classes

Base Weapon Class

Create new Blueprint extending from Actor named BP_BaseWeapon. For now leave it blank.

Structure with weapon data

It isn’t needed for melee but I would like to show you guys how I’m creating weapons to be easy modified by designers.

Create new structure named FWeaponInfo and add those variables:

Name Type Description
Damage float Base damage for weapon. Default 1.
DistanceModifier float Melee range modifier for this weapon. It’s important that default will be 1.
WeaponMesh Skeletal Mesh Reference to Skeletal Mesh weapon. Default should be leaved as blank.

Basically here you can put all of your mesh statistics and data which you are interested in. (eg. UI texture reference, weapon type enum, attack speed etc)

Data Table to store all weapons data

After creating structure create new Data Table:

createnewdatatable

Which will use FWeaponInfo:

createnewdatatablefromweaponinfo

Pick some name for your Weapons Data Table.

Open it and add one weapon.  Make sure it will have Skeletal Mesh assigned to WeaponMesh.

datatable

Why you should use DataTables? It’s really fast to iterate while using them. You can have one folder in your Content named Data with all of your data tables (eg. enemies stats, perks, level informations) so people won’t be searching in your code / blueprints to change some variable they will have one place with all of them.

You can find more information about Data Tables here.

Damage Interface

Next create new Blueprint Interface named IDamage. It should have two functions:

TakeDamage – with 3 inputs:

  • Damage, float
  • HitResult, Hit Result
  • Instigator, Actor Reference

idamagetakedamage

And GetHoldingWeapon function with one output:

  • Weapon, BP_BaseWeapon reference

idamagegetholdingweapon

Interfaces are used to communicate between classes. You can create function with output as well which is super useful.

Weapon Class / Melee Here

Now go back to your BP_BaseWeapon and add some variables:

Name Type Description
WeaponInfo FWeaponInfo This will store weapon information which will be populated from Data Table.
WeaponInDataTable DataTableRowHandle This is the link to Data Table and specific weapon. Make sure you have selected your data table and pick some weapon!

datatabledefaultvalue

isInAttack bool This bool will represent if this weapon is in attack and we should trace for melee.
isUsingSockets bool This will indicate if melee trace will use sockets or not. We will try to find sockets in weapon and use them if added.
HitActors Actor Reference Array This array will store all actors that have been hit by melee.

In Viewport tab make sure you have added Skeletal Mesh Component which will be root.

skeletalmeshcomponent

Now let’s add some Functions.

Start Attack

startattack

EndAttack

endattack

DoMeshHaveSockets

domeshhavesockets

Sockets names are hard coded as you see. If you want to use them for trace start / end – just put them into your skeletal mesh.

meshsockets

Note: You don’t need to add them – we will have small algorithm to get mesh bounds and calculate start end trace. It’s optional but you will have more control of melee trace with them.

GetTraceLocations – Pure Function with two outputs:

  • TraceStart, Vector
  • TraceEnd, Vector

gettracelocations

This part is important take some time to figure out what it does. Part with sockets is simple but without them it’s more complicated but still with small amount of calculations.

I’m taking box extend of a weapon which will give me lenght on X. Then I need to get the same direction vector (and it depend on weapon – read comments) to multiply my extend with it – so it will point end of the weapon.

What you can do here is to add Socket as Root and rotate your mesh, but more pro way is to have the same rotation for all of the imported weapons. If you are using Infinity Blade weapons they will use Up Vector and if you are using Medieval Bludgeoning Weapons Pack they are using Right Vector multiplied by -1.

GiveDamageOnce with two inputs:

  • To, Actor Reference
  • HitResult, Hit Result

givedamageonce

This is making sure we won’t add damage twice to the same actor in the same attack swipe.

We will be calling this function in tick, during animation that’s why it’s needed.

Now go to Event Graph and add some Events.

Begin Play

beginplay

As you can see it’s responsible for weapon configuration.

tick

This should be self explanatory. Basically weapon is waiting (IsInAttack) to check what is under line trace.

Configuring Character – Attach mesh to hands

Now when we have weapon class ready we need to attach weapon somehow to our character.

I’m using Character with hands (FirstPersonCharacter_MedievalBludgeoningPack) from Medieval Bludgeoning Weapons Pack but it is doable in any assets that you have.

First your Character need to have HoldingWeapon variable – of course extending from BP_BaseWeapon.

Next your Character (or any actor that will use weapons – enemies for example) need to have IDamage interface implemented. So go to your class settings and add IDamage interface.

Then double click on GetHoldingWeapon to override interface function and return HoldingWeapon.

getholdingweaponoverride

Now in your Begin Play you need to:

  • Spawn the weapon,
  • Make sure spawned weapon is Holding Weapon,
  • Attach it into hands,

characterbeginplay

Let weapon know to trace and do damage

Now we need to inform holding weapon that we would like to trace and do melee damage. What’s the best way to do this? Use animations and anim notifies.

Pack that I’m using have couple of attack animation and I will use them, but you can use any animation you have.

First create new Blueprint extending from AnimNotifyState named Notify_MeleeDamage. Open it and Override two functions:

Received_NotifyBegin

animnotify_start

Received_NotifyEnd

animnotify_end

Now open some attack animations and add you notify when attack should appear.

And that’s it! If you want to add damage to actors/enemies you need to add IDamage interface to them and add Event Take Damage. AI isn’t in scope of this tutorial but it’s on my list 😉

Final Effect

12 thoughts on “Plug and Play Melee Tutorial

  1. Hi Again, I have a new question. How I Know which kind of object I just hit? I want to make different effects to eatch kind of object type.

    For example, I want make a spark + sound if I hit a static mesh, after hit a wall. and thanks again for your time 🙂

  2. Hi, I have a problem with the GiveDamageOnce function inside baseweapon, when I call “Take Damage” in “target” I can not link to “To” on the output node, says it is not compatible, any idea?

  3. Hi,
    Finished the tutorial.
    Implemented the damage interface. Its as simple as can get. call event >reduce health by damage > debug print string

    what I noticed is that the event in never called, so “give damage once” function must have some issues. Even if I hardcode the damage not taken from a variable it still doesnt call the event not pass the value.
    Any idea what I could $#$%& up?

Leave a Reply